Windows下Python select.select() 错误10022
我有一个类(是从QThread派生的),它通过select.select()从多个套接字接收服务器的数据:
# -*- coding: utf-8 -*-
from PyQt4.QtCore import QThread, pyqtSignal
import json
import select
class MainSocketThread(QThread) :
disconnected_by_admin = pyqtSignal()
disconnected_by_network = pyqtSignal(bool)
def __init__(self, connects_dict=None) :
QThread.__init__(self)
self.connects = connects_dict
if not self.connects:
self.connects={}
def run(self) :
try:
while 1 :
inputready, outputready, exceptready = select.select(self.connects.keys(),
[], [])
for s in inputready :
try :
data = self.s_[s].recv(4096)
if not data :
s.close()
self.connects.pop(s)
else :
cmd = json.loads(data)
print s, cmd, 'asd'
# ProcessCommand(s, cmd)
except Exception as e:
s.close()
self.connects.pop(s)
except Exception as e:
print e
self.disconnected_by_network.emit(False)
self.exec_()
这是我在另一个类中创建套接字的方法:
self.connections_dict = {}
self.main_socket_thread = MainSocketThread(self.connections_dict)
if not self.s :
try:
self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.s.connect((host, port))
except Exception as e:
print e, e.__class__()
self.display_connection_status(False)
else:
self.connections_dict[self.s] = self
self.main_socket_thread.start()
self.s.send(json.dumps({'command': 'operator_insite',
'login': self.settings_dict['login'],
'password': hashlib.md5(self.settings_dict['password']).hexdigest()}))
self.display_connection_status(True)
但是每次我尝试从套接字中选择数据时,都会出现select.error 10022的错误。我的代码哪里出问题了?
3 个回答
0
通过临时接收代码进行解决:
def recv(self, sck):
data = ''
sck.settimeout(None)
data = sck.recv(1024)
sck.settimeout(0.1)
while 1:
line = ''
try:
line = sck.recv(16384)
except socket.timeout:
break
if line == '':
break
data += line
return data
0
你确定self.connects不是空的吗?这让我想起在Windows上,当你把三个空列表传给select.select()
时会出现的错误。
无论如何,错误代码10022代表的是EINVAL,意思是传入了无效的参数。所以我建议你仔细检查一下传给引发异常的函数的参数(看看套接字是否打开等等...)
0
好的,我很早就解决了这个问题。这里有一个使用Pyqt的解决方案:
class UpQSocket(QTcpSocket):
data_ready = pyqtSignal(unicode)
def __init__(self):
QTcpSocket.__init__(self)
self.wait_len = ''
self.temp = ''
self.setSocketOption(QTcpSocket.KeepAliveOption, QVariant(1))
self.readyRead.connect(self.on_ready_read)
def connectToHost(self, host, port):
self.temp = ''
self.wait_len = ''
self.abort()
QTcpSocket.connectToHost(self, host, port)
def close(self):
QTcpSocket.close(self)
def send(self, data):
self.writeData('%s|%s' % (len(data), data))
def on_ready_read(self):
if self.bytesAvailable():
data = str(self.readAll())
while data:
if not self.wait_len and '|' in data:#new data and new message
self.wait_len , data = data.split('|',1)
if match('[0-9]+', self.wait_len) and (len(self.wait_len) <= MAX_WAIT_LEN) and data.startswith('{'):#okay, this is normal length
self.wait_len = int(self.wait_len)
self.temp = data[:self.wait_len]
data = data[self.wait_len:]
else:#oh, it was crap
self.wait_len , self.temp = '',''
return
elif self.wait_len:#okay, not new message, appending
tl= int(self.wait_len)-len(self.temp)
self.temp+=data[:tl]
data=data[tl:]
elif not self.wait_len and not '|' in data:#crap
return
if self.wait_len and self.wait_len == len(self.temp):#okay, full message
self.data_ready.emit(self.temp)
self.wait_len , self.temp = '',''
if not data:
return