pysctp中出现的IOError: [Errno 11] Resource temporarily unavailable以及无限重复接收的问题
2017-04-27 19:48
656 查看
记录一次异常的SCTP连接错误
最近公司的一个项目,需要用到SCTP协议来传输diameter协议内容。于是最近研究了下SCTP协议在python中的实现。
SCTP协议的python实现非常少,搜了下,只有pysctp这个库,而且只能运行于Linux系统。于是就按照对于TCP的理解,写了一个简单的服务器和客户端的实现。
开发环境:Ubuntu16.04,;python2.7;Pycharm。
在pycharm的自带终端Terminal中debug过程中,我发现client客户端在连接上服务器之后,服务器端经常会出现一个错误,错误异常为:IOError: [Errno 11] Resource temporarily unavailable :
虽然问题定位到sctp_recv_msg这个函数,但是我发现只要connect成功,并不需要收发数据,就会触发这个错误。而且不是百分之百,会概率出现,而且有时连接成功后,发送一个data块,服务器再往回返,会收到无限多个重复的data块。使用wireshark抓包也看不出来有什么问题。
百思不得其解啊,CSDN / stackoverflow什么的都搜了个遍也没找到解决问题的方案,本来已经想要放弃了,打算底层socket的收发使用C语言/C++来封装,使用python来调用socket接口,虽然实现起来可能比全python稍微麻烦一点,但起码能跑起来。。。
最后,我分别使用命令行重新试了下,
一切正常,问题就这么解决了。WTF…
事后回想,问题大概率是出在pycharm的终端上;但是同事使用debian命令行也曾出现过无限多次重复接收的问题。。不知道为啥了…反正现在已经好了
而Errno 11的问题,还没有明确解决方案。暂时定位为不能使用非阻塞,即setblocking(1),不能为0…
如果还有问题,欢迎回帖/发邮件讨论。ayocross1@gmail.com
20170608更新部分:
1. 无限循环接收问题,将sctp_recv函数改为普通的recv函数后,再没出现过;
2. [Errno 11] Resource temporarily unavailable问题,暂时替代解决方案同样已找到。
20170821最后更新:
做完这个项目之后,一直忘了更新这个问题的解决方案,今天看当时的日志文档才记起来。。最终解决方案如下:
出现此问题的原因的pysctp项目源码中,_sctp.c文件 1549行,最后一个函数:
作者忘记给flags赋初始值,所以才导致异常,因此改正方法很简单:int flags = 0;
python setup.py install安装即可。问题再也不会出现。
最近公司的一个项目,需要用到SCTP协议来传输diameter协议内容。于是最近研究了下SCTP协议在python中的实现。
SCTP协议的python实现非常少,搜了下,只有pysctp这个库,而且只能运行于Linux系统。于是就按照对于TCP的理解,写了一个简单的服务器和客户端的实现。
开发环境:Ubuntu16.04,;python2.7;Pycharm。
在pycharm的自带终端Terminal中debug过程中,我发现client客户端在连接上服务器之后,服务器端经常会出现一个错误,错误异常为:IOError: [Errno 11] Resource temporarily unavailable :
Traceback (most recent call last): File "/home/test/Downloads/pycharm-community-2017.1.1/helpers/pydev/pydevd.py", line 1578, in <module> globals = debugger.run(setup['file'], None, None, is_module) File "/home/test/Downloads/pycharm-community-2017.1.1/helpers/pydev/pydevd.py", line 1015, in run pydev_imports.execfile(file, globals, locals) # execute the script File "/home/test/PycharmProjects/sctp_socket/server.py", line 47, in <module> fromaddr, flags, msg, notif = conn_sock.sctp_recv(BUFSIZE) File "/home/test/sctp_env/local/lib/python2.7/site-packages/sctp.py", line 1206, in sctp_recv (fromaddr, flags, msg, _notif) = _sctp.sctp_recv_msg(self._sk.fileno(), maxlen) IOError: [Errno 11] Resource temporarily unavailable
虽然问题定位到sctp_recv_msg这个函数,但是我发现只要connect成功,并不需要收发数据,就会触发这个错误。而且不是百分之百,会概率出现,而且有时连接成功后,发送一个data块,服务器再往回返,会收到无限多个重复的data块。使用wireshark抓包也看不出来有什么问题。
百思不得其解啊,CSDN / stackoverflow什么的都搜了个遍也没找到解决问题的方案,本来已经想要放弃了,打算底层socket的收发使用C语言/C++来封装,使用python来调用socket接口,虽然实现起来可能比全python稍微麻烦一点,但起码能跑起来。。。
最后,我分别使用命令行重新试了下,
python server.py
python client.py
一切正常,问题就这么解决了。WTF…
事后回想,问题大概率是出在pycharm的终端上;但是同事使用debian命令行也曾出现过无限多次重复接收的问题。。不知道为啥了…反正现在已经好了
——–
0502更新部分:经过多次测试,多次重复接收问题是因为:当socket关闭时,recv端会接收到无限多次msg为空的消息,如果没有对msg进行判断的话,会无线循环接收。。因此,解决办法就是加一个判断句:if not msg: break而Errno 11的问题,还没有明确解决方案。暂时定位为不能使用非阻塞,即setblocking(1),不能为0…
——–
最后贴一段简单的server和client代码,copy下来就能跑。当然需要先安装pysctp这个库(这个库需要先安装Debian/Ubuntu sudo apt-get install libsctp-dev lksctp-tools,不然会报错找不到文件)。。如果下面程序运行报错的话把中文去了试试。# -*- coding: utf-8 -*- # 实现简单的socket服务器功能 import socket import sctp from time import ctime HOST = '' PORT = 3868 BUFSIZE = 1024 ADDR = (HOST, PORT) socket_serv = sctp.sctpsocket(socket.AF_INET, socket.SOCK_STREAM,None) # , sctp.IPPROTO_SCTP socket_serv.initparams.max_instreams = 3 socket_serv.initparams.num_ostreams = 3 #socket_serv.initparams.max_attempts = 2 #socket_serv.initparams.set_max_init_timeo(0) socket_serv.bindx([ADDR]) socket_serv.listen(5) # socket_serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # socket_serv.setblocking(0) socket_serv.events.data_io = 1 socket_serv.events.clear() while True: print '等待用户连接...' conn_sock, addr = socket_serv.accept() print '有用户接入:', addr msg = '' while True: # msg= conn_sock.recv(BUFSIZE) fromaddr, flags, msg, notif = conn_sock.sctp_recv(BUFSIZE) print 'recv: %s' % msg if not msg: break conn_sock.sctp_send('当前时间:%s...发过来的是%s' % (ctime(), msg)) conn_sock.close() socket_serv.close()
# -*- coding:utf-8 import _sctp from sctp import * server = "localhost" tcpport = 3868 if _sctp.getconstant("IPPROTO_SCTP") != 132: raise "getconstant failed" client_sock = sctpsocket(socket.AF_INET, socket.SOCK_STREAM, None) saddr = (server, tcpport) print "TCP ", saddr, " ----------------------------------------------" client_sock.initparams.max_instreams = 3 client_sock.initparams.num_ostreams = 3 #client_sock.initparams.max_attempts = 2 #client_sock.initparams.set_max_init_timeo(0) # tcp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # client_sock.setblocking(0) client_sock.events.clear() client_sock.events.data_io = 1 # 要获取消息的流编号,SCTP 需要启用套接字选项 sctp_data_io_event client_sock.connect(saddr) while 1: while True: data = raw_input('INPUT: ') if not data: break client_sock.sctp_send(data) fromaddr, flags, msg, notif = client_sock.sctp_recv(1024) # print " Msg arrived, flag %d" % flags #if flags & FLAG_NOTIFICATION: # raise "We did not subscribe to receive notifications!" #else: # print "%s____" % msg, cont print "%s____" % msg break client_sock.close()
如果还有问题,欢迎回帖/发邮件讨论。ayocross1@gmail.com
20170608更新部分:
1. 无限循环接收问题,将sctp_recv函数改为普通的recv函数后,再没出现过;
2. [Errno 11] Resource temporarily unavailable问题,暂时替代解决方案同样已找到。
20170821最后更新:
做完这个项目之后,一直忘了更新这个问题的解决方案,今天看当时的日志文档才记起来。。最终解决方案如下:
出现此问题的原因的pysctp项目源码中,_sctp.c文件 1549行,最后一个函数:
static PyObject* sctp_recv_msg(PyObject* dummy, PyObject* args) { int fd, max_len; struct sockaddr_storage sfrom; socklen_t sfrom_len = sizeof(sfrom); int family; int len; int port; char cfrom[256]; char *msg; int size; int flags; struct sctp_sndrcvinfo sinfo; ...
作者忘记给flags赋初始值,所以才导致异常,因此改正方法很简单:int flags = 0;
python setup.py install安装即可。问题再也不会出现。
相关文章推荐
- 解决VMware8安装CentOS等系统时出现Fatal IO error 11(Resource temporarilt unavaliable) on Xshell:1问题
- OSError: [Errno 11] Resource temporarily unavailable
- v4l打开video设备 ,执行VIDIOC_DQBUF,出现Resource temporarily unavailable 问题
- v4l打开video设备 ,执行VIDIOC_DQBUF,出现Resource temporarily unavailable 问题【转】
- 在Linux环境上面,su切换到oracle时出现"-bash:fork:Resource temporarily unavailable"问题
- socket Resource temporarily unavailable,errno代码为11(EAGAIN)
- TNS-00510 IBM/AIX RISC System/6000 Error: 11: Resource temporarily unavailable
- 解决登录linux服务器出现Resource temporarily unavailable问题——增加用户线程数
- Nginx出现open() XXX failed (11: Resource temporarily unavailable)-nginx与smb之间的灵异事件
- 解决Cygwin下Emacs启动时出现Doing vfork:resource temporarily unavailable问题
- Linux Error: 11: Resource temporarily unavailable
- mac终端打开出现问题:[forkpty: Resource temporarily unavailable]
- TNS-12518,TNS-12536,TNS-00506,Linux Error: 11: Resource temporarily unavailable
- Resource temporarily unavailable,errno代码为11(EAGAIN)
- E:Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)
- E:Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)
- 关于su时出现“-bash:fork:Resource temporarily unavailable”
- E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
- unix:/passenger_helper_server failed (11: Resource temporarily unavailable)
- linux下,su用户时,出现提示:-bash: fork: retry: Resource temporarily unavailable的解决办法