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

为何我的Unix Domain DGRAM Socket运行后服务器无输出?

问题原因分析与修复方案

嘿,这个问题其实挺典型的,我帮你拆解下问题根源和修复方法:

核心问题:客户端把数据发给了自己,而非服务端

你看客户端代码里的sendto调用:

sendto(CliFD, buf, sizeof(buf), 0, (struct sockaddr *)&cliaddr, len)

这里的目标地址用的是cliaddr——也就是客户端自己绑定的/var/run/lcli.sock,相当于把数据发给了自己,服务端的/var/run/lsvr.sock根本没收到任何数据,自然不会输出内容。

还有两个次要问题需要修正

  1. 服务端recvfrom的len参数未初始化:recvfrom的第6个参数是传入传出参数,必须先初始化为地址结构的大小,否则可能触发未定义行为。
  2. 客户端无需强制绑定地址(可选优化):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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:36:24