2012-09-20 259 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