我在使用Python和"纯"时使用所谓的抽象命名空间的unix socket(US)有一个奇怪的问题。 C(Python 3.x但看起来像2.x有同样的问题)。 "正常"插座就像一个魅力。随着"抽象"一个美国我的代码只有在我使用相同的代码平台" (C或Python)。
首先我认为它与memset
/ str(n)cpy
有关(请参阅Can not connect to an abstract unix socket in python),但事实并非如此。
测试矩阵(srv - server,cli - client):
/proc/net/unix
/ lsof
或strace
没有显示任何异常:
工作"正常" socket C客户端:
// ...
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_LOCAL, sun_path=@"/var/tmp/sock.tmp"}, 110) = 0
// ...
行为不端"摘要" socket C客户端:
// ...
socket(PF_LOCAL, SOCK_STREAM, 0) = 3
connect(3, {sa_family=AF_LOCAL, sun_path=@"/var/tmp/sock.tmp"}, 110) = -1 ECONNREFUSED (Connection refused)
// ...
Python bug还是什么......?
使用我的测试矩阵的代码示例:https://gist.github.com/soutys/ffbe2e76a86835a9cc6b
原始代码/样本:
有关系统和汇编的更多信息:
gcc
编译的所有C测试文件(例如:gcc -Wall -Wextra -pedantic -o abs_cli abs_cli.c
); 答案 0 :(得分:0)
将UNIX域套接字绑定到抽象名称时,addrlen参数应为sizeof(struct sockaddr_un的sun_family)+抽象名称中的字符数+ 1.“+1”用于抽象前面的空字节sockaddr_un的sun_path中的名字。我们来看一个例子:
C中的服务器
int sockfd;
struct sockaddr_un addr;
/* create socket, set addr.sun_family, set addr.sun_path to
null byte followed by abstract_name */
bind(sockfd, (struct sockaddr *)&addr, sizeof(addr.sun_family) +
strlen(abstract_name) + 1);
Python中的客户端:
client = socket.socket(socket.AF_UNIX, ...)
client.connect( "\0abstract_name" )
参考文献: