如何在 pysctp 库中使用sctpsocket_udp类



我正在尝试使用 pysctp 库设置一个基本的 SCTP 客户端/服务器示例。我想使用sctp.sctpsocket_udp类,因为根据相关的文档字符串:

UDP 样式的 SCTP 套接字可以通过单个套接字容纳多个关联。

。这是我需要的功能。这是我到目前为止所拥有的:

server_sock = sctp.sctpsocket_udp(socket.AF_INET)
server_sock.bind((str(ip_address), port))
server_sock.listen(16)
server_sock.settimeout(1)
while not done:
time.sleep(3)
fromaddr, flags, msg, notif = server_sock.sctp_recv(3*1024*1024)

当然,为了简洁起见,我省略了诸如进口之类的内容。最重要的是,当执行此操作时,我收到以下错误:

正在阻止IOError: [错误 11] 资源暂时不可用

相应的堆栈跟踪指示问题出现在对_sctp.sctp_recv_msg(...)

跟踪的输出显示以下内容:

1032 socket(PF_INET, SOCK_SEQPACKET|SOCK_CLOEXEC, IPPROTO_SCTP) = 3
1033 getsockopt(3, 0x84 /* SOL_??? */, 2, "n37737710`352", [8]) = 0
1034 getsockopt(3, 0x84 /* SOL_??? */, 11, "", [10]) = 0
1035 bind(3, {sa_family=AF_INET, sin_port=htons(9000), in_addr=inet_addr("127.0.0.1")}, 16) = 0
1036 listen(3, 16)                           = 0
1037 ioctl(3, FIONBIO, [1])                  = 0
1038 mmap(NULL, 3149824, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd621646000
1039 recvmsg(3, 0x7ffe1a59ba40, 0)           = -1 EAGAIN (Resource temporarily unavailable)

我试图重新启动我的计算机,以防有一些资源挂起,但这没有任何帮助。

解决了这个问题。

在引擎盖下,调用socket.settimeout(1)或类似调用我也尝试过的socket.setblocking(False),会导致底层套接字设置为非阻塞。这成为一个问题的原因是,虽然大多数套接字操作(例如,只是在sctp.sctpsocket_udp对象上调用的正常socket.recvmsg被委托给 pythonsocket对象,但sctp_*调用不会,它们是通过 pysctp 的_sctp.cC 扩展组件处理的。这意味着,当您执行导致底层套接字为非阻塞的操作(例如socket.settimeout(1)(然后使用sctp_*函数之一,而不是超时然后获得socket.timeout异常时,您最终会进入底层 C 扩展的这一部分:

size = sctp_recvmsg(...)
if(size < 0){
free(msg);
PyErr_SetFromErrno(PyExc_IOError);
return ret;
}

因此,获取上面引用的 BlockingIOError。解决方案是使用非阻塞模式而不是为超时而烦恼,然后捕获BlockingIOError而不是socket.timeout,只需检查异常的errno属性以确保它是EAGAIN因此指示当时没有可用数据,所以睡觉或其他东西,然后再试一次。

相关内容

  • 没有找到相关文章

最新更新