crossplatform.ru

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

2 страниц V  < 1 2  
Ответить в данную темуНачать новую тему
> "Склеивание" сообщений ТСР
pwp2008
  опции профиля:
сообщение 27.10.2015, 19:49
Сообщение #11


Студент
*

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

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




Репутация:   0  


Цитата(ViGOur @ 27.10.2015, 10:30) *
4 байта было сказано для примера, ты сам решай, какой длины будет у тебя поле длина пакета. К тому же жестко указывать размер нельзя, а только sizeof(int), так как под разными системами int разного размера.
............................

Большое спасибо за пример. Еще, если можно, ряд уточнений.
1. Для моей задачи длина сообщений от 14 до 130 байт, поэтому вполне для длины хватит и 1-го байта.
Прилично ли считывать 1 байт? Хотя, судя по тому, что и 4 байта могут идти частями, думаю, что вполне
прилично.
2. Посоветуйте, какая технология может быть, чтобы не было 2-го входа в слот по сигналу ReadyRead ?
Ведь вполне возможно, что пока я буду выделять и возможно обрабатывать "склееные" сообщения и\или
ждать пока соберется все "разрезанное" сообщение, система может мне устроить второй вход в незаконченный
слот. Реентерабельность тут как то не просматривается.
Не снимать же connect по входу в слот обработки и назначать его потом снова перед выходом?
signal(readyRead)\slot -> обработка сообщений ТСР по идеологии Qt.
Я конечно попробую разобраться с вышеприведенным примером, т.к. в QT для сокета нет метода recv.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 28.10.2015, 9:41
Сообщение #12


Мастер
******

Группа: Модератор
Сообщений: 3291
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

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




Репутация:   40  


1. Почему нет? Ты можешь считать за один раз сколько тебе нужно, а там уже разобрать эти данные на 1 байт + данные + склеенное сообщение (если будет и отправить склеенной для следующего разбора)
2. Синхронизация, используй QMutex, чтобы пока один поток не отработал, другой не вошел для чтения.

Метод recv был для примера, ты можешь так же в место него использовать read... :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
pwp2008
  опции профиля:
сообщение 29.10.2015, 19:14
Сообщение #13


Студент
*

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

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




Репутация:   0  


Цитата(ViGOur @ 28.10.2015, 9:41) *
1. Почему нет? Ты можешь считать за один раз сколько тебе нужно, а там уже разобрать эти данные на 1 байт + данные + склеенное сообщение (если будет и отправить склеенной для следующего разбора)

----------------------------------------------------------------------------------------
По обработке склеенных\разделенных блоков ТСР в Qt 4.5. Привожу лишь существенный код.
Файл - mainwin_02.h
class MainWin_02 : public QMainWindow
{
    Q_OBJECT
public:
    QByteArray srv_R1;   // для ответа сервера
    QQueue <QByteArray> queueMsg;
    void handleQueue();
    bool f_queue;
..........................
public slots:
    void slotGetResponse();
};

Файл - mainwin_02.cpp
MainWin_02::MainWin_02(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWin_02)
{
................................................
//------------------------------------
    // Описание сокета.
    m_pTcpSocket = new QTcpSocket(this);
    connect(m_pTcpSocket,SIGNAL(connected()),SLOT(slotConnected()));
    connect(m_pTcpSocket,SIGNAL(readyRead()),SLOT(slotGetResponse()));
//------------------------------------
void MainWin_02::slotGetResponse()
{
    // читаем склееные и неполные сообщения по сигналу SIGNAL(readyRead()
    int k1,tLen;
    int kk = m_pTcpSocket->bytesAvailable();
    tLen = kk;
    bool f_queue = false;    // признак постановки в очередь
    while (tLen >0) {
        srv_R1.clear();
        srv_R1 = m_pTcpSocket->peek(1);
        k1= srv_R1[0];
        if (tLen >=k1) {
            srv_R1.clear();
            srv_R1 = m_pTcpSocket->read(k1+1);  // читаем вместе с длиной
            tLen = tLen-(k1+1);
            queueMsg.enqueue(srv_R1);               // пишем в очередь
            f_queue = true;
        } else break;    // выйдем, если неполное сообщение и ждем остаток
    }
    if (f_queue) {
        // выполнить обработку очереди
        handleQueue();
    }
}
void MainWin_02::handleQueue()
{
    // обработка очереди сообщений
    while (!queueMsg.isEmpty()) {
        srv_R3.clear();
        srv_R3 = queueMsg.dequeue();
        // далее обработка сообщения ..................................
        qDebug() << "r3="<< srv_R3.toHex() <<srv_R3.data()<< "ostatok="<<queueMsg.count();
    }
}

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 24.1.2020, 14:04