开发者

Python select.select() error 10022 on windows

I got class (subclassed from QThread), that recieve data from server at many sockets by 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) :
开发者_如何学Python        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_()

And that's how i create socket(in other class) :

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)

But i got select.error 10022 every time trying to select from sockets. What is wrong with my code?


are you sure self.connects is not empty ? This reminds me of the error you get on Windows when passing 3 empty lists to select.select().

In any case, 10022 is EINVAL meaning an invalid argument has been supplied. So I'd carefully trace the arguments passed to the function raising the exception (seeing if the sockets are open, etc...)


Soldev by temporary recieve code:

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


Okay. I solved this problem long ago. And here is solution using 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜