Reputation: 31
I am working on a cross-platform game using C/C++ and socket. I am using UDP broadcast (e.g. send to xx.xx.xx.255 if on a C-type LAN address) for discovering of nearby players in LAN game playing.
The issue is the Mac/iOS version can not receive broadcast UDP packet that sent by others (neither from Mac/iOS , nor from windows), while windows version is able the receive broadcast packet from Mac/iOS. Thus Mac/iOS can not discover any nearby players while windows can discover all nearby players. On the same socket handle, sending/receiving normal UDP packet works on all platforms (sent to a specific address instead of the broadcast address).
Every testing device has only one NIC, which is connected to a single WIFI router. Addresses are dynamically allocated by DHCP on the WIFI router. The socket is bind to exact local address instead of 0.0.0.0, and I am using port 19190. [ Thanks for reading my question :) ]
Following is the code for initializing the socket on all platforms. I do set the SO_BROADCAST flag on Mac/iOS otherwise UDP broadcast packet won't be sent successfully.
BOOL Socket::__Create(const struct sockaddr &BindTo, int addr_len, int nSocketType, BOOL reuse_addr, int AF)
{
ASSERT(m_hSocket == INVALID_SOCKET);
m_hSocket = socket(AF, nSocketType, 0);
if(INVALID_SOCKET != m_hSocket)
{
int on = 1;
if(SOCK_STREAM == nSocketType)
{ linger l = {1,0};
VERIFY(0==::setsockopt(m_hSocket,SOL_SOCKET,SO_LINGER,(char*)&l,sizeof(linger)));
#if defined(PLATFORM_MAC) || defined(PLATFORM_IOS)
VERIFY(0==::setsockopt(m_hSocket,SOL_SOCKET,SO_NOSIGPIPE,(void *)&on, sizeof(on)));
#endif
}
#if defined(PLATFORM_MAC) || defined(PLATFORM_IOS)
else if(SOCK_DGRAM == nSocketType)
{
VERIFY(0==::setsockopt(m_hSocket,SOL_SOCKET,SO_BROADCAST,(void *)&on, sizeof(on)));
}
#endif
if(reuse_addr)
{ VERIFY(0==setsockopt(m_hSocket,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on)));
}
if(0==bind(m_hSocket,&BindTo,addr_len))
{
return TRUE;
}
}
_LOG_WARNING("Socket Error = "<<GetLastError());
Close();
return FALSE;
}
Here is the receiving code:
BOOL Socket::__RecvFrom(LPVOID pData, UINT len, UINT& len_out, struct sockaddr &target, int addr_len, BOOL Peek)
{
SOCKET_SIZE_T la = addr_len;
int l = (int)recvfrom(m_hSocket,(char*)pData,len,Peek?MSG_PEEK:0,&target,&la);
if(l==SOCKET_ERROR)return FALSE;
len_out = l;
return la == addr_len;
}
Upvotes: 3
Views: 2105
Reputation: 19385
Did you try to bind the socket to the broadcast address (the one you are sending to) ? – ElderBug
Also, it's not working when you bind to 0.0.0.0 ? – ElderBug
Upvotes: 0