【发布时间】:2022-01-01 11:41:19
【问题描述】:
我正在为 Ubuntu 18.04 上的 UNIX 域数据报套接字 (UDS) IPC 创建 C 服务器和 Python 客户端。我的场景是:Python 作为使用 fork-execv 创建的子进程运行,其中 C 是父进程。 Python 客户端在 socket.recvfrom 上阻塞,直到 C 服务器发送数据。当 C 服务器向 Python 客户端发送数据时,C 将阻塞 recvfrom,直到 Python 使用 sendto 向 C 发送数据。
我已经将 UDS 用于 C 客户端和 C 服务器,没有任何问题,但是 C-Python 设置导致了一些问题。对于这个 Python 版本,我使用了 https://lloydrochester.com/post/c/unix-domain-socket-datagram 的示例。
我在 C 中创建了一个服务器套接字并绑定到它;它返回文件描述符 5:
int64_t * create_socket_server(struct sockaddr_un svaddr, int64_t retvals[])
{
int sfd, j;
ssize_t numBytes;
socklen_t len;
char buf[BUF_SIZE];
retvals[0] = 0;
retvals[1] = 0;
sfd = socket(AF_UNIX, SOCK_DGRAM, 0); /* Create server socket
if (sfd == -1)
return retvals;
if (remove(SV_SOCK_PATH) == -1 && errno != ENOENT)
return retvals;
memset(&svaddr, 0, sizeof(struct sockaddr_un));
svaddr.sun_family = AF_UNIX;
strncpy(svaddr.sun_path, SV_SOCK_PATH, sizeof(svaddr.sun_path) - 1);
if (bind(sfd, (struct sockaddr *) &svaddr, sizeof(struct sockaddr_un)) == -1)
return retvals;
retvals[0] = sfd;
retvals[1] = (int64_t)&svaddr;
return retvals;
}
我没有在 C 端创建或显式连接到客户端套接字。
在 Python 端,我绑定到客户端套接字。这是我的 Python 代码,遵循引用的示例,但有所改动以适合我的用例:
#!/usr/bin/python3
import socket
import os, os.path
csock_file = "/tmp/py_sock"
ssock_file = "/tmp/ud_ucase"
if os.path.exists(csock_file):
os.remove(csock_file)
csock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
csock.bind(csock_file) # Bind to the server socket
return_msg = "Got it"
while True:
(bytes, address) = csock.recvfrom(720)
msg = bytes.decode('utf-8')
print("Python received")
if msg != "Code_99":
print('address:',address,'received:',msg)
csock.sendto(str.encode(return_msg), ssock_file)
if msg == "Code_99":
print("closing")
#Close the socket
我希望 recvfrom 在 Python 和 C 中都被阻塞,因为 Python 应该阻塞直到 C 发送,但是当我让它处于阻塞状态(默认)时,Python 在调用 (bytes, address) = csock.recvfrom 时阻塞这两个进程(720),C 无法继续。
如果我使用 csock.setblocking(False) 将其设置为非阻塞,我会收到以下错误消息:
(bytes, address) = csock.recvfrom(720)
BlockingIOError: [Errno 11] Resource temporarily unavailable
所以我的问题是为什么 Python 会阻塞这两个进程,为什么我会在非阻塞模式下收到该错误消息?
感谢您的帮助。
【问题讨论】:
-
你可以设置一个超时
socket.settimeout(value)如果没有接收到它会抛出socket.error异常,你可以使用try和catch来实现 -
你知道为什么它会在阻塞模式下阻塞两个进程吗?我以为只有 Python 会阻塞。
-
我没有看到向客户端发送响应的代码,你能分享一下,以便我找出问题所在
-
在我调用 (bytes, address) = csock.recvfrom(720) 的地方还没有发送数据,因为我们刚刚连接。 Python连接并调用recvfrom后,服务器会发送数据。
标签: python c python-3.x sockets