Разбираюсь с программированием сетей windows, пишу на VC++ 2008.
Пытаюсь организовать многоадресную UDP рассылку в локальной сети с двумя машинами (192.168.0.2, 192.168.0.3 и маршрутизатором 192.168.0.1).
Ниже приведен текст программы, в зависимости от флага flgSender программа будет или отправлять (true) или получать (false) пакеты.
При вызове WSAJoinLeaf() получаю ошибку 10049 Требуемый адрес для своего контекста неверен.
Делаю по книге Джонс-Оланд, ошибки не вижу.
Помогите.
#include <winsock2.h>
#include <Ws2tcpip.h> // для IP_MULTICAST_TTL
#include <conio.h>
int main() {
const bool flgSender = true; // флаг Отправитель или Получатель
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" ); // или "192.168.0.2", все равно не помогает
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( "192.168.0.2" ); // эта машина будут рассылать
remote.sin_port = htons( 5680 );
// Здесь ошибка 10049 Требуемый адрес для своего контекста неверен.
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;
}