Python AF_UNIX 客户端 C 服务器

Roy*_*lls 5 c python sockets

我是Python初学者,两天前编写了第一个程序。我在 AF_UNIX 的 python 客户端和 C 服务器中遇到连接问题。我有带有 AF_LOCAL 的 C 套接字服务器。

#define NAME "#/tmp/kvsd"

int
main()
{
    int sock, msgsock, rval;
    struct sockaddr_un server;
        char buf[1024];


        unlink(NAME);
        printf("before socket \n");
        sock = socket(AF_LOCAL, SOCK_STREAM, 0);
        if (sock < 0) {
                perror("opening stream socket");
                exit(1);
        }
        memset(&server, 0, (sizeof (server)));
        server.sun_family = AF_LOCAL;
        memcpy(server.sun_path, NAME, strlen(NAME));
        server.sun_path[0] = 0;
        printf("before bind \n");

        int len = strlen(server.sun_path) + sizeof(server.sun_family);
        if (bind(sock, (struct sockaddr *) &server, len)) {
                perror("binding stream socket");
                exit(1);
        }

        printf("before listen \n");
        if (listen(sock, 5) == -1) {
                perror("listen");
                exit(1);
        }
        printf("before accept \n");
        msgsock = accept(sock, 0, 0);
        printf("accepted \n");
        if (msgsock == -1)
                perror("accept");
        else do {
                bzero(buf, sizeof(buf));

                printf("before read  \n");
                if ((rval = read(msgsock, buf, 1024)) < 0)
                        perror("reading stream message");
                else if (rval == 0)
                        printf("Ending connection\n");
                else
                        printf("-->%s\n", buf);
        } while (rval > 0);
        close(msgsock);
        close(sock);
        unlink(NAME);
}
Run Code Online (Sandbox Code Playgroud)

和 Python AF_UNIX client.py:-

####### CLIENT CODE #######

from socket import *

# Create an unbond and not-connected socket.
sock = socket(AF_UNIX, SOCK_STREAM)

# Connect to the peer registered as "MyBindName" in the abstract namespace. Note the '\0'.
str = "\0/tmp/kvsd\0"

print "len ", len (str)
sock.connect("\0/tmp/kvsd")

# Wait for message
msg = sock.recv(100)
print msg

# Send reply
sock.send("Hi there!\n")

# Block until new message arrives
msg = sock.recv(100)

# When the socket is closed cleanly, recv unblocks and returns ""
if not msg:
    print "It seems the other side has closed its connection"

# Close it
sock.close()
Run Code Online (Sandbox Code Playgroud)

但是当我运行客户端时,出现以下错误:

[root@mat afunix]# python ./client.py len 11 Traceback (最近一次调用最后): 文件 "./client.py", 第 13 行, in sock.connect("\0/tmp/kvsd") 文件"",第 1 行,连接套接字中。错误:[Errno 111] 连接被拒绝 [root@mat afunix]#

我正在尝试使用 UNIX 套接字的抽象命名空间,但我的 python 客户端无法连接到 c 服务器。

我尝试在没有抽象名称空间的情况下它可以工作。(将 server.c 中的 NAME 宏更改为“/tmp/kvsd”,并将 sock.connect 的参数更改为“/tmp/kvsd”)。

有人可以帮我找出确切的问题是什么吗?

提前致谢。

fal*_*tru 4

以下线路有问题。

    int len = strlen(server.sun_path) + sizeof(server.sun_family);
Run Code Online (Sandbox Code Playgroud)

server.sun_path 现在具有前导空字符。所以 strlen(server.sun_path) 是 0。您需要将上面的行更改如下:

    #include <stddef.h>

    ....

    int len = offsetof(struct sockaddr_un, sun_path) + strlen(NAME);
Run Code Online (Sandbox Code Playgroud)

然后,它就会起作用。

编辑:更新了代码以使用 offsetof 以避免填充问题。(谢谢你,阿尔克)

PS:我假设服务器和客户端都使用不带尾随空字节的名称。如果您使用带有尾随空字节的名称,请向 中添加 1 len