nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
1

Реализация сервера у Шлее

27.04.2018, 20:41. Показов 1675. Ответов 7
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
У Шлее есть пример кода реализации сервера в главе: "Программирование поддержки сети".
Вопрос: зачем в слоте, связаном с обрабокой сигнала readyRead(), цикл for? При чтении блока данных, отправленных клиентом, этот цикл до конца доходит один раз. Если убрать цикл, и вместо break поставить return, то ничего в работе кода не меняется. Или я что-то не учитыввю? Было предположение, что, пока код находится в этом слоте, может измениться bytesAvailable(), и тогда можно обрабатывать следующие блоки не выходя из слота, но оказалось, что, без выхода из слота, bytesAvailable() не изменяется, даже если приходят новые пакеты.
Код слота у Шлее:
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void MyServer::slotReadClient()
{
    QTcpSocket* pClientSocket = (QTcpSocket*)sender();
    QDataStream in(pClientSocket);
    in.setVersion(QDataStream::Qt_4_5);
    for (;;) {
        if (!m_nNextBlockSize) {
            if (pClientSocket->bytesAvailable() < sizeof(quint16)) {
                break;
            }
            in >> m_nNextBlockSize;
        }
 
        if (pClientSocket->bytesAvailable() < m_nNextBlockSize) {
            break;
        }
        QTime   time;
        QString str;
        in >> time >> str;
 
        QString strMessage = 
            time.toString() + " " + "Client has sent - " + str;
        m_ptxt->append(strMessage);
 
        m_nNextBlockSize = 0;
 
        sendToClient(pClientSocket, 
                     "Server Response: Received \"" + str + "\""
                    );
    }
}
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
27.04.2018, 20:41
Ответы с готовыми решениями:

Реализация сервера
Как реализовать Клиент - сервер. что написать в сервере ( чтобы он обращался к базе данных Access)...

Реализация клиент сервера
Здравствуйте! Нашел все таки тему для своего дипломного проекта - система тестирования знаний с...

Реализация прокси сервера
Добрый вечер Прошу помощи с реализацией прокси сервера, в частности описания общей архитектуры...

Реализация сервера xmpp на Java
Хочу написать сервер xmpp на Java. Что должен уметь сервер авторизация клиента, отправка сообщения...

7
2376 / 833 / 317
Регистрация: 10.02.2018
Сообщений: 1,961
28.04.2018, 00:50 2
С точки зрения обычных сокетов, передача по TCP гарантирует лишь отсутствие потерь и сохранение порядка байт. Нет никакой гарантии, что все данные отправленные одним send будут приняты одним recv. Отправленная посылка может быть принята по частям или несколько посылок могут быть приняты за раз. Если требуется что-то сверх этого, то оно реализуется за счёт протокола бегающего по TCP.

В данном примере for позволяет принять и обработать несколько слипшихся сообщений. Глобальная переменная m_nNextBlockSize и break позволяют принять и обработать частично принятые сообщения в последующих вызовах функции. Протокол обмена в данном случае подразумевает, что сообщения от клиента могут посылаться серверу многократно, независимо от получения им ответа от сервера.

ИХМО
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
28.04.2018, 01:33  [ТС] 3
Цитата Сообщение от Ygg Посмотреть сообщение
В данном примере for позволяет принять и обработать несколько слипшихся сообщений. Глобальная переменная m_nNextBlockSize и break позволяют принять и обработать частично принятые сообщения в последующих вызовах функции. Протокол обмена в данном случае подразумевает, что сообщения от клиента могут посылаться серверу многократно, независимо от получения им ответа от сервера.
Всё так, но отсутствие for, в данном коде, никак не мешает всё это делать. Цикла ожидания пакетов, в слоте, как такового, нет (и события здесь не обрабатываются). Заход в слот по сигналу readyRead(), достижение второго if, выход из слота, и так пока весь блок данных не будет доступен для чтения, потом чтение блока и выход из слота.
0
2376 / 833 / 317
Регистрация: 10.02.2018
Сообщений: 1,961
28.04.2018, 01:36 4
nd2, а клиент у вас есть? Если есть, то попробуйте в нём отсылку каждого сообщения вызвать несколько раз в цикле. Полагаю, что должно случиться слипание пакетов, при котором один сигнал на сервере будет соответствовать приёму сразу нескольких сообщений. И в этом случае без for не получится обработать всё.
0
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
28.04.2018, 01:42  [ТС] 5
Цитата Сообщение от Ygg Посмотреть сообщение
а клиент у вас есть?
Есть конечно, я же, прежде чем создать тему, пробовал варианты.
Цитата Сообщение от Ygg Посмотреть сообщение
при котором один сигнал на сервере будет соответствовать приёму сразу нескольких сообщений. И в этом случае без for не получится обработать всё.
Словами можешь описать, как код с for будет работать в данном случае?
0
2376 / 833 / 317
Регистрация: 10.02.2018
Сообщений: 1,961
28.04.2018, 01:49 6
Лучший ответ Сообщение было отмечено nd2 как решение

Решение

Цитата Сообщение от nd2 Посмотреть сообщение
Словами можешь описать, как код с for будет работать в данном случае?
bytesAvailable будет содержать два сообщения.
Без for обработается только одно сообщение.
Второе сообщение останется в буфере.
Повторного сигнала не будет до прихода новых данных.
Если будет for, то оба сообщения достанутся и на них будет ответ.

Я полагаю, что сигнал испускается не на каждый принятый байт, а на пачку байт.
Но тут нужно реализацию смотреть...
1
nd2
3437 / 2816 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426
28.04.2018, 03:02  [ТС] 7
Цитата Сообщение от Ygg Посмотреть сообщение
bytesAvailable будет содержать два сообщения.
Без for обработается только одно сообщение.
Второе сообщение останется в буфере.
Повторного сигнала не будет до прихода новых данных.
Если будет for, то оба сообщения достанутся и на них будет ответ.
Ты прав. Вариант, когда сразу несколько переданных блоков доступны для чтения, я не проверил.
0
Эксперт С++
8385 / 6147 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
02.05.2018, 11:43 8
Удобно слать "строками" и читать построчно, т.е. с читать разделителем сообщений "\r\n"
Т.е использовать canReadLine() и readLine().
1
02.05.2018, 11:43
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.05.2018, 11:43
Помогаю со студенческими работами здесь

Socket - реализация клиент-сервера
если честно, никогда не задавался целью, как на .Net реализовать клиент-сервер, но вот приперло, а...

Реализация асинхронного клиента и сервера
Пытался сделать следующее: Клиент подключается к серверу и все время прослушивает его до тех...

Шлее на Qt 5.1
У кого то есть инфа когда эта книга выйдет или не стоит её ждать и учить по Qt 4.8?

Шлее Qt 4.8
Через неделю иду покупать Шлее Qt 4.8, но если у кого то есть в электронном варианте залейте на...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru