C语言UDP套接字传递含char*结构体服务端打印段错误如何解决
错误原因
- 你通过UDP发送的结构体中存储的
char* name是客户端进程的虚拟内存地址,并非实际的字符串内容:该地址仅在客户端当前进程空间有效,发送到服务端后,服务端的独立进程空间中没有对应有效的字符串数据,直接访问就会触发段错误。 - 客户端额外逻辑错误:你先通过
malloc给name分配了内存,紧接着直接把字符串常量的地址赋值给name,不仅造成分配的内存泄漏,还让name指向了只读常量区,逻辑完全错误。
修复方案
把结构体里的char* name改为定长字符数组,这样字符串内容会直接存储在结构体的连续内存空间中,发送结构体时会把实际的字符串内容一起传到服务端,不需要传递仅单进程有效的指针。
修改后的Client.c代码
#include<stdio.h> #include<stdlib.h> #include<unistd.h> #include<string.h> #include<netinet/in.h> #include<arpa/inet.h> #include<sys/types.h> #include<sys/socket.h> #define PORT 8080 #define NAME_LEN 50 // 统一约定名字最大长度 struct StudentInfo { char name[NAME_LEN]; // 替换指针为定长数组 int roll; }student; int main() { // 把字符串内容拷贝到数组中,不要直接赋值指针 strncpy(student.name, "Sara You", NAME_LEN-1); student.name[NAME_LEN-1] = '\0'; // 确保字符串结尾安全 student.roll=124; int network_socket=socket(AF_INET, SOCK_DGRAM, 0); struct sockaddr_in serveraddr; memset(&serveraddr, 0, sizeof(serveraddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(PORT); serveraddr.sin_addr.s_addr=inet_addr("127.0.0.1"); // 客户端指定服务端地址,本地测试用回环地址 sendto(network_socket, &student, sizeof(student),0, (struct sockaddr*) &serveraddr, sizeof(serveraddr)); close(network_socket); return 0; }
修改后的Server.c代码
#include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<sys/types.h> #include<arpa/inet.h> #include<netinet/in.h> #include<sys/socket.h> #include<string.h> #define PORT 8080 #define NAME_LEN 50 // 和客户端保持长度定义一致 struct StudentInfo { char name[NAME_LEN]; // 和客户端结构完全对齐,用定长数组 int roll; } student1; int main() { struct sockaddr_in serveraddr, cliaddr; int network_socket=socket(AF_INET, SOCK_DGRAM, 0); memset(&serveraddr,0,sizeof(serveraddr)); memset(&cliaddr,0,sizeof(cliaddr)); serveraddr.sin_family=AF_INET; serveraddr.sin_port=htons(PORT); serveraddr.sin_addr.s_addr=INADDR_ANY; bind(network_socket, (struct sockaddr*) &serveraddr, sizeof(serveraddr)); int len=sizeof(cliaddr); recvfrom(network_socket, &student1, sizeof(student1), 0, (struct sockaddr*) &cliaddr, &len); printf("Name: %s\n", student1.name); printf("Roll No: %d\n", student1.roll); close(network_socket); return 0; }
内容的提问来源于stack exchange,提问作者Sara Khan
相关产品推荐
相关产品推荐

