无法连接到 python 中的抽象 unix 套接字
Can not connect to an abstract unix socket in python
我有一个用 c++ 编写的服务器,它创建并绑定到一个抽象的 unix 套接字,其名称空间地址为 "[=17=]hidden"
。我还有一个用 C++ 编写的客户端,该客户端可以 成功 连接到我的服务器。顺便说一句,我没有这个客户端的源代码。现在我正尝试使用我在 python 中编写的客户端连接到我的服务器,但没有成功。我不明白为什么我的 python 客户端不工作。我发布了我的服务器和客户端代码的相关部分。
服务器
#define UD_SOCKET_PATH "[=11=]hidden"
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.");
还有我的客户端代码
#! /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 = "[=12=]hidden"
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)
在 运行 连接客户端后,我得到以下错误输出:
connecting to hidden
[Errno 111] Connection refused
关于一些额外的信息,我发布了我工作的 c++ 客户端和非工作的 c++ 客户端的 strace 输出的相关部分:python 客户端:
正在工作的 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 工作 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) = ?
而且当我 运行 我的 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,
但是当我 运行 我的 python 客户端时,strace 上没有显示任何输出。所以看起来我试图连接到一个错误的地址,但我的地址在我的服务器和客户端中都被定义为 "[=17=]hidden"
。
你的 C++ 并没有像你想象的那样做。这一行:
strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1);
将单个空字符 '[=11=]'
复制到 addr.sun_path
。请注意 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.
因此,您的 C++ 实际上连接到位于 "[=14=]"
的抽象域套接字。 Python 在这里做了正确的事情并连接到 "[=15=]hidden"
的抽象域套接字。
我有一个用 c++ 编写的服务器,它创建并绑定到一个抽象的 unix 套接字,其名称空间地址为 "[=17=]hidden"
。我还有一个用 C++ 编写的客户端,该客户端可以 成功 连接到我的服务器。顺便说一句,我没有这个客户端的源代码。现在我正尝试使用我在 python 中编写的客户端连接到我的服务器,但没有成功。我不明白为什么我的 python 客户端不工作。我发布了我的服务器和客户端代码的相关部分。
服务器
#define UD_SOCKET_PATH "[=11=]hidden"
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.");
还有我的客户端代码
#! /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 = "[=12=]hidden"
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)
在 运行 连接客户端后,我得到以下错误输出:
connecting to hidden
[Errno 111] Connection refused
关于一些额外的信息,我发布了我工作的 c++ 客户端和非工作的 c++ 客户端的 strace 输出的相关部分:python 客户端:
正在工作的 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 工作 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) = ?
而且当我 运行 我的 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,
但是当我 运行 我的 python 客户端时,strace 上没有显示任何输出。所以看起来我试图连接到一个错误的地址,但我的地址在我的服务器和客户端中都被定义为 "[=17=]hidden"
。
你的 C++ 并没有像你想象的那样做。这一行:
strncpy(addr.sun_path, UD_SOCKET_PATH, sizeof(addr.sun_path)-1);
将单个空字符 '[=11=]'
复制到 addr.sun_path
。请注意 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.
因此,您的 C++ 实际上连接到位于 "[=14=]"
的抽象域套接字。 Python 在这里做了正确的事情并连接到 "[=15=]hidden"
的抽象域套接字。