C与Python - 使用套接字通信

8 投票
2 回答
4144 浏览
提问于 2025-04-16 22:11

我正在尝试使用UNIX域套接字在一个C程序和一个Python脚本之间进行通信。这个Python脚本通过UNIX域套接字向C程序发送数据。

这是我C程序中相关的代码:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>    
#define UNIX_PATH_MAX 100

int main(void)
{
struct sockaddr_un address;
int socket_fd, connection_fd;
socklen_t address_length;
pid_t child;

socket_fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (socket_fd < 0){
    printf("socket() failed\n");
    return 1;
} 

unlink("/tmp/demo_socket");
memset(&address, 0, sizeof(struct sockaddr_un));

address.sun_family = AF_UNIX;
snprintf(address.sun_path, UNIX_PATH_MAX, "/tmp/demo_socket");

if (bind(socket_fd, (struct sockaddr *) &address, sizeof(struct sockaddr_un)) != 0) {
    printf("bind() failed\n");
    return 1;
}
if(listen(socket_fd, 5) != 0) {
    printf("listen() failed\n");
    return 1;
}

//----------------WHILE LOOP----------------------->
while((connection_fd = accept(socket_fd, 
                            (struct sockaddr *) &address,
                            &address_length)) > -1)
{
.
.
.(doesn't get any further than this)

这是我用来向套接字发送消息的Python脚本:

import socket

s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect("/tmp/demo_socket")
print "Sending..."
s.send("Hello world")
x = s.recv(1024)
print x
s.close()

这个Python脚本出现了“Broken Pipe”的错误。C程序从未进入循环,因为accept()函数失败并返回了'-1'。

为什么accept()会失败?我该怎么做才能让它成功呢?

2 个回答

2

根据我找到的一个例子,你在调用bind的时候,传入的长度不应该包括结尾的或者填充用的空字符,这些在sockaddr_un里是不算的。

你可以试试:

size_t addrlen;
const char* sockname = "/tmp/demo_socket";

/* ... */

address.sun_family = AF_UNIX;
snprintf(address.sun_path, UNIX_PATH_MAX, sockname);
addrlen = sizeof(address.sun_family) + strlen(sockname);

if (bind(socket_fd, (struct sockaddr *) &address, addrlen) != 0) {
    printf("bind() failed\n");
    return 1;
}

另外,正因为这样,你就不需要调用memset了。

2

如果我没记错的话,address_length 需要在调用 accept() 之前初始化为 sockaddr_un 的大小。在调用过程中,它会被填充为实际的对方地址的长度,这个地址会被放入 address 中。

祝好,
马丁

撰写回答