我正在使用C / C和socket进行跨平台游戏 . 我正在使用UDP广播(例如,如果在C型LAN地址上发送到xx.xx.xx.255),用于在LAN游戏中发现附近的玩家 .
问题是Mac / iOS版本无法接收由他人发送的广播UDP数据包(既不是来自Mac / iOS,也不是来自Windows),而Windows版本则能够接收来自Mac / iOS的广播数据包 . 因此,当Windows可以发现附近的所有玩家时,Mac / iOS无法发现任何附近的玩家 . 在同一套接字句柄上,发送/接收普通UDP数据包适用于所有平台(发送到特定地址而不是广播地址) .
每个测试设备只有一个NIC,它连接到一个WIFI路由器 . 地址由WIFI路由器上的DHCP动态分配 . 套接字绑定到精确的本地地址而不是0.0.0.0,我使用端口19190. [感谢您阅读我的问题:)]
以下是在所有平台上初始化套接字的代码 . 我在Mac / iOS上设置了SO_BROADCAST标志,否则UDP广播包将无法成功发送 .
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;
}
这是接收代码:
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;
}
1 回答
您是否尝试将套接字绑定到广播地址(您要发送到的地址)? - ElderBug
此外,绑定到0.0.0.0时它不起作用? - ElderBug