2012-04-19 76 views
2

我試圖編寫一個服務器,它通過UDP接收查詢並通過UDP發送響應。我遇到的問題是,當我嘗試發送我的回覆時,出現「101網絡無法訪問」錯誤。基於這個問題here我試圖取出hints.ai_flags = AI_PASSIVE;線來解決這個套接字UDP:使用來自SendTo()中的Recvfrom()的發件人信息失敗

,但隨後服務器從來沒有成功獲取該消息。我查看了addrinfo的手冊頁,聽起來好像AI_PASSIVE標誌已設置,套接字只能使用recvfrom(),而如果未設置,則套接字只能使用sendto()。儘管我已經在網上看到了大量的例子,人們只用一個套接字就可以完成這兩個例子;我錯過了什麼?

相關代碼:

struct addrinfo hints; 
struct addrinfo *serverinfo; 
memset(&hints,0,sizeof hints); 
hints.ai_family = AF_UNSPEC; 
hints.ai_socktype = SOCK_DGRAM; 
hints.ai_flags = AI_PASSIVE; 

int status = getaddrinfo(NULL, port, &hints, &serverinfo); 
int sock = socket(serverinfo->ai_family, serverinfo->ai_socktype, serverinfo->ai_protocol); 
status = bind(sock, serverinfo->ai_addr, serverinfo->ai_addrlen); 
freeaddrinfo(serverinfo); 

// poll until there's an incoming packet 

struct sockaddr sender; 
socklen_t sendsize = sizeof(sender); 
bzero(&sender, sizeof(sender)); 

recvfrom(sock, message, sizeof(message), 0, &sender, &sendsize); 

// message processing 

sendto(sock, response, sizeof(response), 0, (struct sockaddr *)&sender, sendsize); 

是的,我有錯誤檢查所有的呼叫(這就是我如何發現問題);爲了簡潔起見,這裏只是被遺漏在這裏。

+0

的'的getaddrinfo(3)'頁我的系統上顯示初始化'hints.ai_protocol','hints.ai_canonname','hints.ai_addr'和'之前調用hints.ad_next''的getaddrinfo(3) '。這些可能很重要,也嘗試初始化它們。 (當然,你把你的整個結構歸零;這就是爲什麼這只是一個註釋而已......) – sarnold 2012-04-19 21:54:33

+0

你是否在兩種方式下都有同樣的錯誤?含義A-> B-> A(獲取錯誤)以及B-> A-> B(獲取錯誤?) – noMAD 2012-04-19 22:30:03

回答

7

您不應該使用struct sockaddr來將源地址存儲在recvfrom調用中,它可能無法表示IP套接字地址。

對於IPv4地址,您應該使用struct sockaddr_in,對於IPv6地址應該使用struct sockaddr_in6,或者更好的是使用struct sockaddr_storage來應對。

struct sockaddr_storage sender; 
socklen_t sendsize = sizeof(sender); 
bzero(&sender, sizeof(sender)); 

recvfrom(sock, message, sizeof(message), 0, (struct sockaddr*)&sender, &sendsize); 
相關問題