Разбираюсь с программированием сетей Windows, пишу на VC++ 2008.
Пытаюсь организовать многоадресную UDP рассылку в локальной сети с двумя машинами (192.168.0.2, 192.168.0.3 и маршрутизатором 192.168.0.1).
Ниже приведен текст программы, в зависимости от флага flgSender программа будет или отправлять (true) или получать (false) пакеты.
Отправитель пакеты шлет, это видно в окне.
Получатель застревает в WSARecvFrom().
Пример не работает даже когда получатель и отправитель запущены на одной машине.
Делаю по книге Джонс-Оланд, ошибки не вижу.
Тут дело может быть не в программировании, а настройках сети.
Файрвол отключен.
В маршруты добавлено
1.
Сетевой адрес Маска сети Адрес шлюза Интерфейс Метрика
238.1.1.0 255.255.255.0 On-link 192.168.0.2 11
Кто нибудь может помочь?
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
#include <winsock2.h>
#include <Ws2tcpip.h> // для IP_MULTICAST_TTL
#include <conio.h>
#include <iostream>
using namespace std;
#define ERROR_HANDLER( OBJ ) { cout << #OBJ << (OBJ) << endl; exit(- 1 ); }
#define WSA_LAST_ERROR_HANDLER { \
DWORD dw = WSAGetLastError(); \
if ( NO_ERROR != dw ) { \
char *MsgBuf; \
FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, 0 , dw, 0 , (LPSTR) &MsgBuf, 0 , 0 ); \
cout << dw << ' ' << MsgBuf << endl; \
exit(- 1 ); \
} \
}
#pragma comment( lib, "Ws2_32.lib" )
int main() {
const bool flgSender = false;
WSADATA WSAData;
int ErrCode = WSAStartup( MAKEWORD( 2 , 2 ), &WSAData );
if ( 0 != ErrCode ) ERROR_HANDLER( ErrCode );
SOCKET s = WSASocket( AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0 , 0 , WSA_FLAG_MULTIPOINT_C_LEAF | WSA_FLAG_MULTIPOINT_D_LEAF );
if ( INVALID_SOCKET == s ) WSA_LAST_ERROR_HANDLER;
sockaddr_in local;
memset( &local, 0 , sizeof( local ) );
local.sin_family = AF_INET;
local.sin_addr.s_addr = inet_addr( "127.0.0.1" );
local.sin_port = htons( flgSender ? 5678 : 5679 );
if ( 0 != bind( s, (sockaddr*) &local, sizeof( local ) ) ) WSA_LAST_ERROR_HANDLER;
int optval = 8 ;
if ( 0 != setsockopt( s, IPPROTO_IP, IP_MULTICAST_TTL, (char*) &optval, sizeof( optval ) ) ) WSA_LAST_ERROR_HANDLER;
sockaddr_in remote;
memset( &remote, 0 , sizeof( remote ) );
remote.sin_family = AF_INET;
remote.sin_addr.s_addr = inet_addr( "238.1.1.1" );
remote.sin_port = htons( 5680 );
SOCKET sR = WSAJoinLeaf( s, (sockaddr*) &remote, sizeof( remote ), 0 , 0 , 0 , 0 , JL_BOTH );
if ( INVALID_SOCKET == sR ) WSA_LAST_ERROR_HANDLER;
if ( s != sR ) ERROR_HANDLER( sR );
// Цикл отправки / получения сообщений
int i;
WSABUF Buffer;
Buffer.len = sizeof( i );
Buffer.buf = (CHAR*) &i;
if ( flgSender ) {
for ( i = 0 ; ! _kbhit(); i++ ) {
DWORD NumberOfBytesSent = 0 ;
if ( 0 != WSASendTo( s, &Buffer, 1 , &NumberOfBytesSent, 0 , (sockaddr*) &remote, sizeof( remote ), 0 , 0 ) ) WSA_LAST_ERROR_HANDLER;
cout << i << endl;
Sleep( 1000 );
}
}
else {
for ( ; ! _kbhit(); ) {
DWORD NumberOfBytesRecvd = 0 , Flags = 0 ;
sockaddr_in From;
memset( &From, 0 , sizeof( From ) );
INT Fromlen = sizeof( From );
if ( 0 != WSARecvFrom( s, &Buffer, 1 , &NumberOfBytesRecvd, &Flags, (sockaddr*)&From, &Fromlen, 0 , 0 ) ) WSA_LAST_ERROR_HANDLER;
cout << i << endl;
}
}
if ( 0 != closesocket( s ) ) WSA_LAST_ERROR_HANDLER;
if ( 0 != WSACleanup() ) WSA_LAST_ERROR_HANDLER;
return 0 ;
}