[英]C unix domain sockets, recvfrom() doesn't set struct sockaddr* src_addr
我正在編寫一個通過unix域套接字偵聽UDP數據包的應用程序。 請考慮以下代碼塊。
int sockfd;
struct sockaddr_un servaddr;
sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
if(sockfd < 0)
{
perror("socket() failed");
}
unlink(port);
bzero(&servaddr, sizeof(servaddr));
servaddr.sun_family = AF_LOCAL;
strcpy(servaddr.sun_path, port);
if(bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0)
{
perror("bind() failed");
close(sockfd);
}
int n;
struct sockaddr_un cliaddr;
socklen_t len = sizeof(cliaddr);
discovery_msgs client_message;
bzero(&client_message, sizeof(client_message));
// Wait for a message to be received
n = recvfrom(sock_fd, &client_message, sizeof(client_message), 0,
(struct sockaddr *) &cliaddr, &len);
// At this point n = 560, client_message is filled with the expected data
//len = 0 and cliaddr has no information about the client that sent the data
現在client_message
的類型並不重要,我收到一個UDP數據包, client_message
包含我期望的所有數據。 當我在調用recvfrom
后查看cliaddr
和len
時,問題就出現了。 cliaddr
不會被recvfrom
修改,就像通常使用普通網絡TCP / UDP一樣,並且len
在調用后設置為0(這意味着recvfrom沒有將數據寫入&cliaddr
)。 我需要使用unix域路徑填充cliaddr
的信息,以便我可以發送響應。
我究竟做錯了什么?
當使用Unix域套接字時,解決方案是綁定客戶端上的套接字。 否則,在sendto()
,為發送UDP數據包而創建的瞬態路徑名會立即消失,這就解釋了為什么客戶端的地址信息在服務器端不可用。
請參閱Stevens Network Programming第419頁或查看此示例以獲取解決此問題的示例客戶端實現:libpix.org/unp/unixdgcli01_8c_source.html
#include "unp.h"
int
main(int argc, char **argv)
{
int sockfd;
struct sockaddr_un cliaddr, servaddr;
sockfd = Socket(AF_LOCAL, SOCK_DGRAM, 0);
bzero(&cliaddr, sizeof(cliaddr)); /* bind an address for us */
cliaddr.sun_family = AF_LOCAL;
strcpy(cliaddr.sun_path, tmpnam(NULL));
Bind(sockfd, (SA *) &cliaddr, sizeof(cliaddr));
bzero(&servaddr, sizeof(servaddr)); /* fill in server's address */
servaddr.sun_family = AF_LOCAL;
strcpy(servaddr.sun_path, UNIXDG_PATH);
dg_cli(stdin, sockfd, (SA *) &servaddr, sizeof(servaddr));
exit(0);
}
注意: unp.h
定義了Bind()
,它只是bind()
和一些錯誤檢查(在整個史蒂文斯網絡編程中常用)。 以相同的方式, (SA *)
等同於(struct sockaddr *)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.