2012-09-20 207 views
6

我必须接收UDP广播(在Ubuntu中,如果有任何区别)。使用Wireshark,我可以看到从服务器发送的数据包,我可以看到它被我的客户端机器接收,但是我的程序完全没有意义。这是我有:接收UDP广播

sockaddr_in si_me, si_other; 
int s; 
assert((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP))!=-1); 
int port=6000; 
int broadcast=1; 

setsockopt(s, SOL_SOCKET, SO_BROADCAST, 
      &broadcast, sizeof broadcast); 

memset(&si_me, 0, sizeof(si_me)); 
si_me.sin_family = AF_INET; 
si_me.sin_port = htons(port); 
si_me.sin_addr.s_addr = INADDR_ANY; 

assert(::bind(s, (sockaddr *)&si_me, sizeof(sockaddr))!=-1); 

while(1) 
{ 
    char buf[10000]; 
    unsigned slen=sizeof(sockaddr); 
    recvfrom(s, buf, sizeof(buf)-1, 0, (sockaddr *)&si_other, &slen); 

    printf("recv: %s\n", buf); 
} 

它在调试模式下进行编译时,断言没有被编译过程中删除,我的程序只是recvfrom块。

有没有其他箍我必须跳过来接收一个untargeted UDP广播?

编辑:只是更多的信息,我有两台计算机连接在一个专用的开关,没有外部干扰。我的客户端计算机上还连接了第二块网卡,可以连接到公司网络,该网卡也可以工作。

我可以ping外部(互联网工作)和我的服务器机器(再加上我可以看到Wireshark中的实际数据包),但你永远不知道什么可能会导致此问题。

+0

此代码适用于我(稍作修改后,使其通过C编译进行编译)。可能'bind'绑定了错误的接口?什么'netstat -an | grep 6000'在客户端机器上返回? –

+0

是的,它应该工作,但它不适合我。 'netstat -an'显示没有开放的6000端口,我已经加倍检查了(我也试过使用“重用”udp标志)。 – Blindy

+0

'bind()'实际上并不打开一个端口。只有'connect()'和'listen()'这样做。但是你不需要通过listen()来打开一个端口来接收UDP广播。 –

回答

2

事实证明我的代码非常好,就像我想的那样。网络设置本身存在问题。

对于后代,我在自己的集线器上设置了两台静态IP计算机,而不是使用服务器机器中的内置DHCP服务器为其他计算机分配IP地址。漂亮的本地化为我的问题,但你永远不知道..

1

要发送和接收广播

  1. 确保子网掩码是正确的。在windows中用于广播数据包的掩码无关紧要,但不在linux中。

  2. 绑定套接字到INADDR_ANY

  3. setsockopt的广播

  4. 呼叫SENDTO与sendaddr.sin_addr.s_addr = inet_addr( “your_interface_broadcast_address”)。 或 - 使用其广播IP地址为每个接口多次呼叫sento。

  5. call recvfrom。在调用recvfrom之前的任何时间,设置长度参数。

+7

为什么发布这个?你可以看到我在2012年的原始信息中完成了这个工作...... – Blindy