2011-03-28 110 views
1

我正在編寫一個測試UDP網絡服務的小程序。允許服務的實現爲會話創建一個新的套接字並從那裏響應客戶端,然後客戶端需要與此地址對話(類似於TFTP)。WSARecvFrom來自未連接的UDP套接字不返回

最小客戶端SANS錯誤檢查看起來是這樣的:

int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); 

sockaddr_in destaddr = { ... }; 
MSGBUF msg[] = { ... }; 
DWORD sent; 
WSASendTo(fd, msg, sizeof msg/sizeof *msg, &sent, 0, (sockaddr *)sa, sizeof sa, 0, 0); 

char buffer[4096]; 
MSGBUF rcvmsg = { sizeof buffer, buffer }; 
DWORD received; 
sockaddr_storage sa; 
socklen_t sa_len = sizeof sa; 
DWORD flags = 0; 
WSARecvFrom(fd, &rcvmsg, 1, &received, &flags, (sockaddr *)&sa, &sa_len, 0, 0); 

客戶端工作正常,如果服務器從最初的消息被髮送到同一個地址和端口響應,但是從另一個端口答覆將被丟棄客戶掛在WSARecvFrom

如預期的那樣,將套接字顯式綁定到{ AF_INET, INADDR_ANY, 0 }以強制分配本地端口,或調用listen(fd, 5);沒有任何區別。

WSASendTo中是否有隱式連接UDP套接字的內容,如果有,我該怎麼做才能避免這種情況?

回答

0

這是一個防火牆問題。將應用程序添加到允許接收傳入流量的程序列表中可以解決問題。

2

UDP沒有連接。數據報被髮送到端口和從端口發送;這是單向溝通。

這聽起來像你的服務器讓自己被分配一個臨時端口(即傳遞0作爲sockaddr_in中的端口),而不是使用特定的端口。這不起作用。

由於UDP沒有連接的概念,每次發送數據時,都可能從不同的端口發送;第一次發送不保留給定的端口,它只是從它發送一個數據報,然後讓它離開。

您的服務器應該將自己綁定到特定端口。

+0

我意識到這一切。我的問題是協議特別允許服務器這樣做,只要它在原始地址和端口上聯繫客戶端,因此客戶端需要能夠接收來自未知的遠程地址和端口的回覆(這就是爲什麼我在未連接的套接字上使用WSARecvFrom的原因 - 接受任何回覆並瞭解回覆的發送地址)。 – 2011-03-29 05:28:19