我正在编写一个通过 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
包含我期望的所有数据。当我看到时问题就开始了cliaddr
and len
打电话后recvfrom
. cliaddr
未被修改recvfrom
就像正常网络 TCP/UDP 一样len
调用后设置为0(这意味着recvfrom没有写入数据&cliaddr
)。我需要以下信息cliaddr
填充 unix 域路径,以便我可以发送响应。
我究竟做错了什么?
解决方案是在使用 Unix 域套接字时在客户端绑定套接字。否则,为发送 UDP 数据包而创建的临时路径名将立即消失sendto()
,这就解释了为什么客户端的地址信息在服务器端不可用。
请参阅史蒂文斯网络编程第 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);
}
Note: unp.h
定义Bind()
这就是简单的bind()
进行一些错误检查(在史蒂文斯网络编程中常用)。以相同的方式,(SA *)
相当于(struct sockaddr *)
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)