Название: Работа с QTcpSocket Отправлено: Yury от Январь 26, 2018, 13:34 Всем привет.
Пишу клиент-серверное приложение по передаче файлов по сети и есть вопрос. Как только на сервере я записываю данные в сокет методом write(),то на каждый его вызов на клиенте срабатывает сигнал readyRead(), правильно?И каждый сигнал обрабатывается слотом. А если я на сервере вызову в цикле 10 раз метод write() с новым QByteArray каждый раз в качестве аргумента?На клиенте мне приходит только самый первый пакет,остальные 9 почему-то не доходят,хотя с сервера вроде ушли. В чем может быть дело?И как мне лучше переслать 10 файлов с сервера на клиент? Название: Re: Работа с QTcpSocket Отправлено: Yury от Январь 26, 2018, 13:37 Вот мой код:
void MainWindow::sendToServer(const QString &msg) { Package package; package.smallNum = 4; package.bigNum = 1567; package.str = msg; package.array = "jkgferwgfrewjfwewef"; QByteArray arrBlock; QDataStream out(&arrBlock, QIODevice::WriteOnly); out.setVersion(QDataStream::Qt_4_8); out << package.smallNum; out << package.bigNum; out << package.str; out << package.array; int lBytes = 0; lBytes = tcpSocket->write(arrBlock); qDebug() << lBytes << "were sent"; } void MainWindow::slotConnected() { ui->textEdit->append("Recieved the connected() signal from server"); } void MainWindow::slotSendButton() { int packageNum = 0; for(int i = 0; i < 10; ++i) { packageNum++; sendToServer("Hello, server. How are you? " + QString::number(packageNum)); } } То есть по нажатию кнопки 10 раз вызовется wriye(), а на другом конце сигнал readyRead() срабатывает только раз.Иногда 2) Название: Re: Работа с QTcpSocket Отправлено: vicprog от Январь 26, 2018, 14:18 Как мне кажется, ты забыл сделать после
Код: tcpSocket->write(arrBlock); Размер пакета для tcp в среднем около 1500 байт. Посчитай сам, сколько туда твоих сообщений поместится. Название: Re: Работа с QTcpSocket Отправлено: Yury от Январь 26, 2018, 14:26 С flush() уже доходит 2 пакета,но все равно не все)Остальные 8 теряются.Размер одного отсылаемого пакета тут около 90 байт,не больше 100.
Название: Re: Работа с QTcpSocket Отправлено: vicprog от Январь 26, 2018, 14:40 Посмотрите, что flush возвращает.
Еще можно поставить waitForBytesWritten() и тоже посмотреть что возвращает. А еще посмотрите на размер приходящих пакетов. Может они спресовались в один пакет? Название: Re: Работа с QTcpSocket Отправлено: ssoft от Январь 26, 2018, 14:43 Несколько пакетов может объединяться в один readyRead, все ли данные вычитываются?
Название: Re: Работа с QTcpSocket Отправлено: kuzulis от Январь 26, 2018, 15:16 Цитировать Как только на сервере я записываю данные в сокет методом write(),то на каждый его вызов на клиенте срабатывает сигнал readyRead(), правильно?И каждый сигнал обрабатывается слотом. Нет. QTcpSocket полностью асинхронный. Вызов QTcpSocket::write() пишет данные во внутренний буффер кдасса QTcpSocket, а уже там, далее эти данные могут быть посланы позже. Все зависит от внутреннего сосояния QTcpSocket и платформы на которой он реализован. В общем случае вот это: Код: void Foo::bar() Не гарантирует что оно будет отослано по-отдельности и прямо сейчас. Оно все зависит от фазы луны, настроект сокета и прочего всего. :) Скорее всего QTcpSocket возмет сразу ABC и запишет в FIFO драйвера (а может и не сразу), а как там уже драйвер отправит их, одному Лешему известно. Название: Re: Работа с QTcpSocket Отправлено: Yury от Январь 26, 2018, 15:34 Да,вы правы!Приходят не по отдельности пакеты,а вместе скомканные.А как их тогда лучше обработать,чтобы разделить на клиенте?Сначала в буфер записать и потом вычленять из него?
Название: Re: Работа с QTcpSocket Отправлено: kuzulis от Январь 26, 2018, 16:10 Цитировать Сначала в буфер записать QTcpSocket уже имеет буфер, т.о. нет необходимости в каком-то дополнительном буфере (но тут кому как удобнее). Цитировать и потом вычленять из него? Да, для этого нужно иметь какой-то протокол обмена (типо придумать заголовки к данными, типа 0x55AA). Для парсинга данных достаточно юзать peek(), read(), bytesAvailable(). Название: Re: Работа с QTcpSocket Отправлено: vicprog от Январь 26, 2018, 16:31 Все зависит от решаемой задачи. Если клиент может подождать и обработать потом пачку сообщений - то да, делать как в предыдущем сообщении.
Если нельзя накапливать и нужна реакция на каждое сообщение - то смотреть в сторону QUdpSocket (но там возможна потеря сообщений при передачи). |