Python select.select () ошибка 10022 на окнах - PullRequest
3 голосов
/ 18 августа 2011

Я получил класс (подкласс от 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 голосов
/ 25 августа 2011

Soldev по временному коду получения:

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 голосов
/ 27 января 2012

Хорошо.Я решил эту проблему давно.И вот решение с использованием 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 голосов
/ 18 августа 2011

Вы уверены, что self.connects не является пустым?Это напоминает мне об ошибке, которую вы получаете в Windows при передаче 3 пустых списков в select.select().

В любом случае, 10022 - это EINVAL, то есть указан неверный аргумент.Поэтому я тщательно отслеживал аргументы, передаваемые функции, вызывающей исключение (проверяя, открыты ли сокеты и т. Д ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...