You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C语言UDP套接字客户端无法接收输出问题求助

问题分析与修复方案

你的UDP服务端和客户端代码存在几个关键问题,导致服务端提前终止且客户端收不到数据,咱们一步步来梳理和修复:

客户端(Client.c)的问题

  • 语法错误int = recvfrom(...) 这里缺少变量名,应该定义一个接收返回值的变量(比如int recv_len
  • recvfrom参数错误:第5个参数需要传入存储发送方地址的sockaddr_in结构体指针,而你传了&network_socket(这是socket文件描述符的地址,完全不对);同时len的初始化错误,应该是sockaddr_in结构体的大小,不是socket文件描述符的大小
  • sendto发送空数据:你调用sendto时发送了0字节数据,虽然UDP允许,但这会导致服务端的recvfrom读取空内容,可能覆盖原本要返回的消息

服务端(Server.c)的问题

  • 客户端地址类型错误client_address被定义为int,但它应该是struct sockaddr_in类型,用来存储客户端的完整地址信息,int类型根本无法容纳地址结构体
  • len初始化错误len = sizeof(client_address) 因为client_address是int,所以这个值是4/8字节,但实际需要的是struct sockaddr_in的大小,这会导致recvfrom调用失败
  • recvfrom覆盖了响应消息:你把客户端发来的数据读到了server_message里,客户端发的是空数据,这会清空原本准备好的响应内容,导致返回给客户端的是空消息

修正后的代码

修正后的Client.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main() {
    int network_socket;
    network_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (network_socket == -1) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    // 发送一个简单的测试数据,而不是0字节
    char msg[] = "Hello from client";
    int send_len = sendto(network_socket, msg, sizeof(msg), MSG_CONFIRM, 
                         (const struct sockaddr *) &server_address, sizeof(server_address));
    if (send_len == -1) {
        perror("sendto failed");
        close(network_socket);
        exit(EXIT_FAILURE);
    }

    char server_response[256];
    struct sockaddr_in from_addr;
    socklen_t len = sizeof(from_addr);
    int recv_len = recvfrom(network_socket, server_response, sizeof(server_response)-1, 0,
                           (struct sockaddr*) &from_addr, &len);
    if (recv_len == -1) {
        perror("recvfrom failed");
        close(network_socket);
        exit(EXIT_FAILURE);
    }
    // 手动添加字符串结束符,确保printf正常输出
    server_response[recv_len] = '\0';
    printf("The server sent the data : %s\n", server_response);

    close(network_socket);
    return 0;
}

修正后的Server.c

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>

int main() {
    char server_message[256] = "you have reached the UDP server";
    int server_socket;
    struct sockaddr_in client_address; // 正确定义客户端地址结构体

    server_socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (server_socket == -1) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    struct sockaddr_in server_address;
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(9002);
    server_address.sin_addr.s_addr = INADDR_ANY;

    int bind_status = bind(server_socket, (struct sockaddr *) &server_address, sizeof(server_address));
    if (bind_status == -1) {
        perror("bind failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    socklen_t len = sizeof(client_address); // 正确初始化地址长度
    char client_msg[256];
    // 读取客户端消息到单独的缓冲区,不覆盖响应消息
    int n = recvfrom(server_socket, client_msg, sizeof(client_msg)-1, 0, 
                    (struct sockaddr *) &client_address, &len);
    if (n == -1) {
        perror("recvfrom failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }
    client_msg[n] = '\0';
    printf("Received from client: %s\n", client_msg);

    // 发送预定义的响应消息
    int send_len = sendto(server_socket, server_message, sizeof(server_message), 0, 
                         (struct sockaddr *) &client_address, len);
    if (send_len == -1) {
        perror("sendto failed");
        close(server_socket);
        exit(EXIT_FAILURE);
    }

    close(server_socket);
    return 0;
}

关键修复点说明

  • 所有系统调用(socket、bind、sendto、recvfrom)都添加了错误检查,方便调试问题
  • 客户端和服务端都使用正确的sockaddr_in结构体来处理地址信息
  • 服务端把客户端消息读到单独的缓冲区,避免覆盖要返回的响应内容
  • 客户端发送非空数据,确保服务端能正确触发后续的响应逻辑
  • 添加了字符串结束符,避免printf输出乱码

内容的提问来源于stack exchange,提问作者Alex Ed

火山引擎 最新活动