crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

> QtcpSocket. Проблема с асинхронностью чтения данных
Andrewshkovskii
  опции профиля:
сообщение 14.12.2011, 23:33
Сообщение #1


Активный участник
***

Группа: Участник
Сообщений: 351
Регистрация: 27.12.2008
Пользователь №: 467

Спасибо сказали: 18 раз(а)




Репутация:   1  


Друзья, в ниже изложенном алгоритме приема данных из сокета я наблюдаю проблему, которую не знаю как решить, может вы мне поможете?
Условие передачи данных по сокетам - %длина_передаваемых_данных%|%сериализированный_json% .
Слот чтения данных соединен с сигналом readyRead. Обменивается сервер и клиент т.н. "Командами", сериализованный JSON с обязательным атрибутом 'command'.
Приходит команда от сервероного сокета (на сервер сайде используются не qt-сокеты, а питоновские, из модуля socket).
Почему-то, при приеме сравнительно большем объеме данных (100к+ символов) возникает следующая проблема:

Но я не успеваю получить их полностью и в этот поток данных команды вливается, почему-то, ещё один поток данных, из следующей команды. Соответственно, при достижении нужного размера полученных данных я отправляю на обработку не валидный JSON. А происходит это так , допустим есть команда, содержащая 100к+ символов. ОТправляем сокету, и пока сокет её получает, отправляет ещё одну, и ещё одну. и всё это дело почему-то перемешивается. А недостающие куски потом прилетают.
Как это может быть?Разве слоты обрабатываются асинхронного ? (софтина не многопоточная). Да и потом, протокол обеспечивает "правильную" последовательность данных, а тут как-то наоборот. Может я не верно слот с сигналом соединил? Использую следующий код :

# -*- coding: utf-8 -*-
from PyQt4.QtCore import QVariant, pyqtSignal, Qt
from PyQt4.QtNetwork import QTcpSocket
from re import match

MAX_WAIT_LEN  = 8

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, Qt.QueuedConnection)

    def connectToHost(self, host, port):
        self.temp = ''
        self.wait_len = ''
        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
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Сообщений в этой теме
- Andrewshkovskii   QtcpSocket. Проблема с асинхронностью чтения данных   14.12.2011, 23:33
- - Влад   Гм. Я правильно понял: у тебя И на серверной сторо...   15.12.2011, 13:27
- - Andrewshkovskii   Гарантированно однопоточные. Никак не могу понять,...   15.12.2011, 19:08
- - ssoft   Могу только пофантазировать пока на тему использов...   16.12.2011, 6:42
- - Влад   Я думаю, что дело тут не в сокетах и не в TCP, а ...   16.12.2011, 13:01
- - Andrewshkovskii   Если бы была ошибка в алгоритме, то он бы не работ...   17.12.2011, 12:19
- - Влад   Ну, вот при обычных условиях - он и не работает :-...   19.12.2011, 10:15
- - PAFOS   может быть у переменной есть ограничение на максим...   20.12.2011, 8:26
- - Andrewshkovskii   Извините друзья, я лежал в больнице, не мог ответи...   26.12.2011, 13:53
- - Andrewshkovskii   В общем есть идея отказаться от сигнальной системы...   27.12.2011, 11:23
- - PAFOS   Цитата(Andrewshkovskii @ 26.12.2011, 14:5...   28.12.2011, 15:40
- - Влад   Я все-таки уверен, что дело не в сигналах и синхро...   29.12.2011, 12:16
- - Andrewshkovskii   Да, дело было не в асинхронности. Проблема с сокет...   10.1.2012, 16:43
- - Andrewshkovskii   Проблема решилась очень просто. settimeout(None) и...   10.1.2012, 19:16


Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 8.5.2024, 23:51