简体   繁体   English

无法连接到python中的抽象unix套接字

[英]Can not connect to an abstract unix socket in python

I have a server written in c++ which creates and binds to an abstract unix socket with a namespace address of "\\0hidden" . 我有一个用c ++编写的服务器,它创建并绑定到名称空间为"\\0hidden"的抽象unix套接字。 I also have a client which is written in c++ also and this client can successfully connect to my server. 我也有一个用c ++编写的客户端,这个客户端可以成功连接到我的服务器。 BTW, I do not have the source code of this client. 顺便说一句,我没有这个客户端的源代码。 Now I am trying to connect to my server using a client I have written in python with no success. 现在我尝试使用我在python中编写的客户端连接到我的服务器但没有成功。 I do not understand why my python client is not working. 我不明白为什么我的python客户端无法工作。 I am posting the relevant parts of my server and client codes. 我发布了服务器和客户端代码的相关部分。

Server 服务器

#define UD_SOCKET_PATH          "\0hidden"
struct sockaddr_un addr;
int fd,cl;

if ( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) 
{
    syslog(LOG_CRIT, "Error creating socket!");
    exit(1);
}

memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_UNIX;
strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1);
unlink(UD_SOCKET_PATH);


if (::bind(fd, (struct sockaddr*)&addr, sizeof(addr)) == -1) 
{
    syslog(LOG_CRIT, "Bind error");
    exit(1);
}

if (listen(fd, MAX_CONN_PENDING) == -1) 
{
    syslog(LOG_CRIT, "Listen error");
    exit(1);
}

syslog(LOG_INFO, "Start listening.");

And my client code 和我的客户端代码

#! /opt/python/bin/python
import os
import socket
import sys
# Create a UDS socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)

server_address = "\0hidden"
print >>sys.stderr, 'connecting to %s' % server_address.decode("utf-8")
try:
    sock.connect(server_address)
except socket.error, msg:
    print >>sys.stderr, msg
    sys.exit(1)

After running the client I get the following error output: 运行客户端后,我得到以下错误输出:

connecting to hidden
[Errno 111] Connection refused

And for some extra information I am posting the relevant parts of the strace outputs of my working c++ client and non-working python client: 对于一些额外的信息,我发布了我的工作c ++客户端和非工作python客户端的strace输出的相关部分:

Working c++ client: 使用c ++客户端:

socket(PF_FILE, SOCK_STREAM, 0)         = 3
connect(3, {sa_family=AF_FILE, path=@""}, 110) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 0), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77d7000
write(1, "Sent message is: 00014 www.googl"..., 38) = 38
write(3, "00014 www.google.com", 20)    = 20
recv(3, "014 Search Engines", 99, 0)    = 18
write(1, "014 Search Engines\n", 19)    = 19
close(3)                                = 0
exit_group(0)                           = ?

None working python client: 没有工作的python客户端:

socket(PF_FILE, SOCK_STREAM, 0)         = 3
connect(3, {sa_family=AF_FILE, path=@"hidden"...}, 9) = -1 ECONNREFUSED (Connection refused)
write(2, "Traceback (most recent call last"..., 35) = 35
write(2, "  File \"./uds.py\", line 13, in <"..., 40) = 40
open("./uds.py", O_RDONLY|O_LARGEFILE)  = 4
fstat64(4, {st_mode=S_IFREG|0755, st_size=839, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7792000
read(4, "#! /opt/python/bin/python\nimport"..., 4096) = 839
write(2, "    ", 4)                     = 4
write(2, "sock.connect('\\0hidden')\n", 25) = 25
close(4)                                = 0
munmap(0xb7792000, 4096)                = 0
write(2, "  File \"/opt/python/lib/python2."..., 64) = 64
open("/opt/python/lib/python2.7/socket.py", O_RDONLY|O_LARGEFILE) = 4
fstat64(4, {st_mode=S_IFREG|0755, st_size=20234, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7792000
read(4, "# Wrapper module for _socket, pr"..., 4096) = 4096
read(4, "oo long.\"\n    errorTab[10064] = "..., 4096) = 4096
write(2, "    ", 4)                     = 4
write(2, "return getattr(self._sock,name)("..., 39) = 39
close(4)                                = 0
munmap(0xb7792000, 4096)                = 0
write(2, "socket", 6)                   = 6
write(2, ".", 1)                        = 1
write(2, "error", 5)                    = 5
write(2, ": ", 2)                       = 2
write(2, "[Errno 111] Connection refused", 30) = 30
write(2, "\n", 1)                       = 1
rt_sigaction(SIGINT, {SIG_DFL, [], 0}, {0x810fbe0, [], 0}, 8) = 0
close(3)                                = 0
exit_group(1)                           = ?

And also when I run my c++ client, I get this strace output from my server: 而且当我运行我的c ++客户端时,我从我的服务器获得这个strace输出:

0, NULL)                      = 12
futex(0x80646a4, FUTEX_CMP_REQUEUE_PRIVATE, 1, 2147483647, 0x8064688, 360) = 10
futex(0x8064688, FUTEX_WAKE_PRIVATE, 1) = 1
accept(5, 

But when I run my python client, no output is shown on strace. 但是当我运行我的python客户端时,没有输出显示在strace上。 So it seems like I am trying to connect to a wrong address, but my address is defined as "\\0hidden" in both my server and my client. 所以我似乎想要连接到错误的地址,但我的地址在我的服务器和客户端都定义为"\\0hidden"

Your C++ doesn't do quite what you think it does. 您的C ++并不能完成您的想法。 This line: 这一行:

strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1);

Copies a single null character '\\0' into addr.sun_path . 将单个空字符'\\0'复制到addr.sun_path Note this line in the manpage for strncpy() : 请注意strncpy()的联机帮助页中的这一行:

If the length of src is less than n, strncpy() writes additional null bytes to dest to ensure that a total of n bytes are written. 如果src的长度小于n,则strncpy()将额外的空字节写入dest以确保总共写入n个字节。

As a result your C++ actually connects to an abstract domain socket at "\\0" . 因此,您的C ++实际上连接到"\\0"处的抽象域套接字。 Python does the right thing here and connects to an abstract domain socket at "\\0hidden" . Python在这里做正确的事情并连接到"\\0hidden"的抽象域套接字。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM