You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 17:54:04