recvfrom 中的分段错误(已创建核心转储)

Posted

技术标签:

【中文标题】recvfrom 中的分段错误(已创建核心转储)【英文标题】:segmentation fault(core dump created) in recvfrom 【发布时间】:2021-12-27 20:55:30 【问题描述】:

我正在编写一个简单的 C 代码来创建一个监听套接字。代码如下:

#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/ip.h>

void main() 
    struct sockaddr_in server;
    struct sockaddr_in client;
    int clientlen;
    char buf[1500];

    int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    memset((char *)&server, 0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_addr.s_addr = htonl(INADDR_ANY);
    server.sin_port = htons(9090);

    if(bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0)
        error("ERROR on binding");

    while(1) 
        bzero(buf, 1500);
        recvfrom(sock, buf, 1500-1, 0, (struct sockaddr *) &client, &clientlen);
        printf("%s\n", buf);
        printf("%d - %s\n", client.sin_port, client.sin_addr.s_addr);
    
    close(sock);

代码编译没有问题,但是当我使用 netcat 通过客户端连接到服务器时:

nc -u 10.0.2.4 9090

我发送了一些消息,消息被回复,然后我收到错误消息。有人知道我为什么会出现这种行为吗? 谢谢。

【问题讨论】:

clientlen 必须初始化为client 的长度。目前它未初始化。 【参考方案1】:

这里有两个主要问题。首先,clientlen 应该包含在调用recvfrom 之前的地址结构的大小,但它是未初始化的。所以设置如下:

int clientlen = sizeof(client);

其次,您使用%s 打印client.sin_addr.s_addr,但该字段不是字符串。您应该使用inet_ntoastruct inaddr_t 转换为字符串:

printf("%d - %s\n", ntohs(client.sin_port), inet_ntoa(client.sin_addr));

【讨论】:

clientlen 的问题已解决,如果我评论第二个 printf 我没有收到任何错误。如果我想打印客户端端口和地址,我仍然会收到错误...

以上是关于recvfrom 中的分段错误(已创建核心转储)的主要内容,如果未能解决你的问题,请参考以下文章

pyqt5 中的分段错误(核心转储)

获取“分段错误核心转储”

使用 pthread_create 时出现“分段错误(核心转储)”

在 C++ 中的向量中键入所有值后出现分段错误(核心转储)

分段错误(核心转储) - 无法访问的计数器值

分段错误(核心转储)