C unix域套接字,recvfrom()不设置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的types并不重要,我正在接收一个UDP数据包, client_message包含了我所期望的所有数据。 调用recvfrom后,我看cliaddrlen时,问题就开始了。 cliaddr不会被recvfrom修改,就像正常的networkingTCP / UDP一样,在调用之后len被设置为0(意味着recvfrom没有写入数据到&cliaddr )。 我需要cliaddr的信息填充unix域path,以便我可以发送一个响应。

我究竟做错了什么?

当使用Unix域套接字时,解决方案是绑定客户端的套接字。 否则,为发送UDP数据包而创建的瞬时路径名在sendto()之后立即消失,这就解释了为什么客户端的地址信息在服务器端不可用。

请参阅Stevens网络编程第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()并带有一些错误检查(通常在整个Stevens网络编程中使用)。 以相同的方式, (SA *)等同于(struct sockaddr *)