为何我的Unix Domain DGRAM Socket运行后服务器无输出?
问题原因分析与修复方案
嘿,这个问题其实挺典型的,我帮你拆解下问题根源和修复方法:
核心问题:客户端把数据发给了自己,而非服务端
你看客户端代码里的sendto调用:
sendto(CliFD, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, len)
这里的目标地址用的是cliaddr——也就是客户端自己绑定的/var/run/lcli.sock,相当于把数据发给了自己,服务端的/var/run/lsvr.sock根本没收到任何数据,自然不会输出内容。
还有两个次要问题需要修正
- 服务端
recvfrom的len参数未初始化:recvfrom的第6个参数是传入传出参数,必须先初始化为地址结构的大小,否则可能触发未定义行为。 - 客户端无需强制绑定地址(可选优化):UDP客户端通常不需要显式绑定自己的socket地址,内核会自动分配临时本地地址,除非你有固定客户端端口的特殊需求。
修复后的代码示例
修复后的服务端代码
/* server */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> #define MPLOGD_SOCK "/var/run/lsvr.sock" void mpExit(const char *msg) { perror(msg); exit(EXIT_FAILURE); } int main(int ac, char *av[]) { char buf[10]; int mpLogFD; socklen_t len = sizeof(struct sockaddr_un); // 初始化地址长度 struct sockaddr_un serverAddress, clientAddress; if((mpLogFD = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0) mpExit("sock"); unlink(MPLOGD_SOCK); memset(&serverAddress, 0, sizeof(serverAddress)); serverAddress.sun_family = AF_LOCAL; strcpy(serverAddress.sun_path, MPLOGD_SOCK); if(bind(mpLogFD, (struct sockaddr *)&serverAddress, sizeof(serverAddress)) < 0) mpExit("bind"); perror("svr"); for(;;){ // 用单独的clientAddress接收客户端地址,避免覆盖服务端自身配置 if(recvfrom(mpLogFD, buf, sizeof(buf)-1, 0, (struct sockaddr *)&clientAddress, &len) < 0) mpExit("recv"); buf[sizeof(buf)-1] = '\0'; // 手动添加结束符,防止字符串越界 printf("Received: %s\n", buf); } }
修复后的客户端代码
/* client */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <sys/un.h> #define SERVER_SOCK "/var/run/lsvr.sock" void mpExit(const char *msg) { perror(msg); exit(EXIT_FAILURE); } int main(int ac, char *av[]) { int CliFD; char buf[10]; struct sockaddr_un serverAddr; // 定义服务端地址结构 if((CliFD = socket(AF_LOCAL, SOCK_DGRAM, 0)) == -1) mpExit("cli sock"); // 初始化服务端地址信息 memset(&serverAddr, 0, sizeof(serverAddr)); serverAddr.sun_family = AF_LOCAL; strcpy(serverAddr.sun_path, SERVER_SOCK); sprintf(buf, "12345678"); if(sendto(CliFD, buf, strlen(buf)+1, 0, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) mpExit("cli send"); perror("cli"); close(CliFD); // 记得关闭socket资源 return 0; }
修复后的运行效果
[root@jyl opt]# ./logsvr & 2033 svr: Success [root@jyl opt]# ./logcli cli: Success Received: 12345678
这样服务端就能正常接收并输出客户端发送的数据了!
内容的提问来源于stack exchange,提问作者umbreLLaJYL
相关产品推荐
相关产品推荐

