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

Unix套接字下Python客户端与C服务端数据传输故障排查求助

排查Unix套接字C服务端与Python客户端通信失败的问题

我帮你梳理下代码里的几个关键问题,这些是导致双向收发失败的核心原因:

1. Accept语句的运算符优先级错误

这是最致命的问题——你的accept赋值语句因为运算符优先级搞错了,导致connection拿到的根本不是有效的套接字描述符:

原代码:

if (connection = accept(globSock, (struct sockaddr*) &addr, &len) < 0)

这里<的优先级高于=,实际执行逻辑是先判断accept(...) < 0,再把布尔结果(0或1)赋值给connection。正确写法需要给赋值语句加括号,确保先完成赋值再判断结果:

if ((connection = accept(globSock, (struct sockaddr*) &addr, &len)) < 0)

2. MakeSocket函数调用参数不匹配

你的makeSocket函数定义需要两个参数:struct sockaddr_un * addr和char* path,但初始化全局套接字时只传了字符串,这会直接导致编译错误。你需要先定义一个struct sockaddr_un变量,再传给函数:

struct sockaddr_un server_addr;
int globSock = makeSocket(&server_addr, "socket.soc");

3. 非阻塞套接字的Recv错误处理不当

你把套接字设为非阻塞模式,但recv返回-1时不一定是真错误——如果是EAGAIN或EWOULDBLOCK,只是表示当前没有数据可读,应该忽略这种情况,而不是直接判定接收失败。

原recv逻辑可以修改为:

else {
    int rc = recv(connection, buffer, BUFFERSIZE-1, 0); // 留一个位置给字符串终止符
    if (rc < 0) {
        // 非阻塞下无数据的情况,不属于错误
        if (errno != EAGAIN && errno != EWOULDBLOCK) {
            perror("recv failed");
            connected = 0;
        }
    } else if (rc == 0) {
        // 客户端主动关闭连接
        printf("Client disconnected\n");
        connected = 0;
        recevd = 0;
    } else {
        // 给接收的字符串加终止符,避免打印乱码
        buffer[rc] = '\0';
        recevd = 1;
        printf("Received: %s\n", buffer);
    }
}

注意要包含errno.h头文件才能使用errno变量。

4. 发送数据后的返回值检查

原代码里的send(connection, "HI", strlen("HI"), 0);没有检查返回值,无法确认数据是否发送成功。可以添加检查逻辑:

ssize_t send_len = send(connection, "HI", strlen("HI"), 0);
if (send_len < 0) {
    perror("send failed");
} else {
    printf("Sent %zd bytes: HI\n", send_len);
}

5. Python客户端缺少接收逻辑

你的Python客户端只发送数据,没有处理C服务端发送的"HI"消息,即使C端修复后发送了数据,客户端也看不到。可以在连接成功后添加接收逻辑:

client.connect("socket.soc")
print("Ready.")
# 接收服务端的初始消息
init_msg = client.recv(1024).decode('utf-8')
print(f"Server says: {init_msg}")

修正后的关键代码片段

C服务端Idle回调修正:

#include <errno.h> // 必须包含这个头文件

// 假设connection、connected、recevd、buffer、addr均已正确定义
if (!connected) {
    socklen_t len = sizeof(addr); // 注意这里要用socklen_t类型,不是int
    if ((connection = accept(globSock, (struct sockaddr*) &addr, &len)) < 0) {
        // 非阻塞下accept返回-1且errno为EAGAIN是正常情况,不是错误
        if (errno != EAGAIN && errno != EWOULDBLOCK) {
            perror("accept failed");
        }
    } else {
        printf("connected\n");
        ssize_t send_len = send(connection, "HI", strlen("HI"), 0);
        if (send_len < 0) {
            perror("send failed");
        } else {
            printf("Sent initial message\n");
        }
        connected = 1;
        recevd = 0;
    }
} else {
    int rc = recv(connection, buffer, BUFFERSIZE-1, 0);
    if (rc < 0) {
        if (errno != EAGAIN && errno != EWOULDBLOCK) {
            perror("recv failed");
            connected = 0;
            recevd = 0;
        }
    } else if (rc == 0) {
        printf("Client disconnected\n");
        connected = 0;
        recevd = 0;
    } else {
        buffer[rc] = '\0';
        recevd = 1;
        printf("Received: %s\n", buffer);
    }
}

Python客户端修正:

# -*- coding: utf-8 -*-
import socket
import os
print("Connecting...")
if os.path.exists("socket.soc"):
    client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    client.connect("socket.soc")
    print("Ready.")
    # 接收服务端的初始HI消息
    try:
        server_msg = client.recv(1024).decode('utf-8')
        print(f"Server: {server_msg}")
    except:
        print("Failed to receive initial message")
    print("Ctrl-C to quit.")
    print("Sending 'DONE' shuts down the server and quits.")
    while True:
        try:
            x = input("> ")
            if "" != x:
                print("SEND:", x)
                client.send(x.encode('utf-8'))
                if "DONE" == x:
                    print("Shutting down.")
                    break
        except KeyboardInterrupt as k:
            print("Shutting down.")
            client.close()
            break
else:
    print("Couldn't Connect!")
print("Done")

把这些问题修复后,应该就能正常实现双向通信了。

内容的提问来源于stack exchange,提问作者Yannik Nelson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:48:38