在创建接受multicast的socket的时候,很多人都这样写:
m_SocketMulticast=//socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); WSASocket(AF_INET,SOCK_DGRAM,0,NULL,0,WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED); sockaddr_in addrMulti; addrMulti.sin_family=AF_INET; addrMulti.sin_addr.s_addr=inet_addr(pIp); addrMulti.sin_port=htons(GROUP_PORT); if( SOCKET_ERROR==bind(m_SocketMulticast,(sockaddr*)&addrMulti,sizeof(addrMulti)) ) { int error_code=WSAGetLastError(); wchar_t pwchar[10]; _itow_s( error_code, pwchar, 10, 10); ::MessageBoxW(NULL,pwchar,_T("Binding the multicast port failed"),MB_OK); return; } bool reuseport=1; setsockopt(m_SocketMulticast,SOL_SOCKET ,SO_REUSEADDR,(const char*)& reuseport,sizeof(bool)); int timeout=1000; setsockopt( m_SocketMulticast,SOL_SOCKET,SO_RCVTIMEO,(const char*)&timeout,sizeof(int) ); sockaddr_in remote; remote.sin_family = AF_INET; remote.sin_port = htons(GROUP_PORT); remote.sin_addr.s_addr = inet_addr(GROUP_IP); SOCKET sockM; if ((sockM = WSAJoinLeaf(m_SocketMulticast, (SOCKADDR *)&remote, sizeof(remote), NULL, NULL, NULL, NULL, JL_BOTH)) == INVALID_SOCKET) { int error_code=WSAGetLastError(); wchar_t pwchar[10]; _itow_s( error_code, pwchar, 10, 10); ::MessageBoxW(NULL,pwchar,_T("Add Multicast Membership Failed!"),NULL); }
Window socket 2.0下,是否可以直接socket(...)来取代WSASocket(...)创建socket,加入multicast组?谢谢!
其实 socket 和 WSASocket 类似的,在socket 内部调用WSASocket,但是dwFlags 却是默认值(调试可知)和你设置的WSA_FLAG_MULTIPOINT_C_LEAF|WSA_FLAG_MULTIPOINT_D_LEAF|WSA_FLAG_OVERLAPPED可能会不同,不同的话,调用WSAJoinLeaf就会失败。
SOCKET __stdcall socket(int af, int type, int protocol)
{
SOCKET result; // eax@5
DWORD v4; // eax@7
LPVOID v5; // [sp+4h] [bp-4h]@3
if ( PrologPointer == Prolog_v2 && DPROCESS::sm_current_dprocess && (v5 = TlsGetValue(DTHREAD::sm_tls_index)) != 0
|| (v4 = SlowPrologOvlp(&v5)) == 0 )
{
if ( af == 17 )
{
if ( protocol > 0 )
protocol = -protocol;
}
result = WSASocketW(af, type, protocol, 0, 0, *((_DWORD *)v5 + 22) == 0);
}
else
{
SetLastError(v4);
result = -1;
}
return result;
}