Russian Qt Forum
Ноябрь 22, 2024, 14:50 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2] 3   Вниз
  Печать  
Автор Тема: QTcpSocket и QThread  (Прочитано 22622 раз)
Harlon
Гость
« Ответ #15 : Июнь 06, 2018, 21:19 »

Нет это просто уже от безысходности я начал пихать его куда попало...
Записан
vic57
Чайник
*
Offline Offline

Сообщений: 90


Просмотр профиля
« Ответ #16 : Июнь 06, 2018, 21:20 »

ну а где у тебя маркер начала/конца блока например?
я в свое время делал так-
1.маркер начала блока - 0xa,0xa,0xa,0xa,0xa,0xa,0xa,0xd - 8 байт
2.циклический номер блока - 0x0 - 0xff - 2 байта
3.длина блока данных - 0x0 - 0xffff - 4 байта
4.блок данных
5. контрольная сумма(опционально) - 4 байта
у тебя нет внутренней структуры данных, поэтому ты и не можешь отловить ошибки

Записан
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #17 : Июнь 06, 2018, 21:23 »

Нет это просто уже от безысходности я начал пихать его куда попало...
Это кусок кода из слота обработки сигнала readyRead? Что делается в отрисовке. Покажите весь слот.
Записан
Harlon
Гость
« Ответ #18 : Июнь 06, 2018, 21:29 »


Код
C++ (Qt)
void MainWindow::sockASCANRead()
{
   QDataStream ds_ascan (socket);
   int i;
   for (;;)
   {
       i++;
       const auto bav = socket->bytesAvailable();
       if (bav < 8192 )
       {
          //если я сюда вставлю socket->readAll(); я буду терять почти все данные, точнее они просто не будут обрабатываться
           return;
       }
 
       QVector <int> ascanArr(2048);
       for (int i = 0; i < 2048; i++)
       {
           ds_ascan.setByteOrder(QDataStream::LittleEndian);
           ds_ascan >> ascanArr[i];
       }
 
       /*QString strs;
       for (int j = 0; j<2048; j++)
       {
       strs = QString::number(ascanArr[i]);
       }
       QFile ff("out.txt");
       if (ff.open(QIODevice::Append))
       {
       QTextStream st (&ff);
       st << strs;
       ff.close();
       }*/

       // ===================== отрисовка графика =====================
       //qDebug() << ascanArr;
 
       QVector <double> x(2048), y(2048);
 
       for (int i=0; i<2048; i++)
       {
           x[i] = i;
           y[i] = ascanArr[i];
       }
 
       // создаем график и добавляем данные:
       ui->widget->addGraph();
       ui->widget->graph(0)->setData(x, y);
       // задаем имена осей координат
       ui->widget->xAxis->setLabel("Время");
       ui->widget->yAxis->setLabel("Амплитуда");
       // задаем размеры осей
       ui->widget->xAxis->setRange(0, 2048);
       ui->widget->yAxis->setRange(-2048, 2048);
       ui->widget->replot();
 
       // ======================== конец отрисовки =====================
   }
 
}
 

Да леший с этой отрисовкой, мне главное целостность данных и скорость передачи (отрисовка дело третье, её можно вообще каждый 10 или 15 раз отрисовывать)
« Последнее редактирование: Июнь 06, 2018, 21:31 от Harlon » Записан
vic57
Чайник
*
Offline Offline

Сообщений: 90


Просмотр профиля
« Ответ #19 : Июнь 06, 2018, 22:10 »

http://www.prog.org.ru/index.php?topic=32063.msg236503#msg236503
делай как здесь, буфер сокета надо очищать, он может тупо переполниться
Записан
Harlon
Гость
« Ответ #20 : Июнь 07, 2018, 08:25 »

А если я в начало буфера допустим строку, допустим char *next_block = "accept"; (6байт)

Код
C
char *next_block = "accept"; //(6 байт)
int n[2048];
//далее заполню массив;
for (int i = 0; i < 2048; i++)
   n[i] = rand() % 4000 - 2000;
err = tcp_write (tpcb, next_block, sizeof(next_block),1)
err = tcp_output (tpcb);
err = tcp_write (tpcb, next_block, 2048 * sizeof(int), 1)
 

А на клиенте:

Код
C++ (Qt)
 
MainWindow :: readSocket()
{
   for(;;)
   {
       if(socket->bytesAvailable() < 6)
           return;
       QByteArray ASData = socket->read(6);
       QString str = "accept", strData = ASData;// если моя не спящая уже 2 недели голова правильно помнит, то в QString можно без проблем  присвоить
                                                                   //QByteArray
 
       if (str == strData)
           return;
       if(socket->bytesAvailable() < 8192)
           return;
 
       ASData = socket->read(8192);
 
       QDataStream stream;
       stream << ASData;
 
       QVector <int> arrData(2048);
       for (int i = 0; i < 2048; i++)
       {
           stream.setByteOrder(QDataStream::LittleEndian);
           stream >> arrData[i];
       }
 
...//дальше там отрисовка, запись в файл и т.д.
 
   }
}
 

И ещё сразу спрошу: что бы запихнуть в несколько потоков отправку сообщения серверу, я предполагаю это лучше делать через отдельный класс унаследованный от QObject, в котором я создам слот Run(), в котором будет выполнятся отправка, НО я не могу представить как передавать туда команду socket->write() из MainWindow... В общем опять каша, подскажите как решить это или тут надо новый класс для сокета делать?
 
Всё с потоками вроде разобрался, осталось только принять нормально.
« Последнее редактирование: Июнь 07, 2018, 15:12 от Harlon » Записан
vic57
Чайник
*
Offline Offline

Сообщений: 90


Просмотр профиля
« Ответ #21 : Июнь 07, 2018, 18:16 »

у тебя однопоточный сервак, зачем тебе многопоточный клиент?
вангую что железка работает на прерываниях и ты не дожидаешься окончания передачи пакета и даешь команду на передачу нового пакета
посмотри рабочий пример
Записан
Harlon
Гость
« Ответ #22 : Июнь 07, 2018, 18:17 »

https://evileg.com/ru/post/152/
Вот так возможно реализовать поток? Передавая свой сокет по ссылке?

Да там есть прерывания...

Блин ты прав, у меня стакается запрос в железке, я допустим посылаю туда char s = 'A'; а получаю строку 'AA' и вот и косячина...

Первый раз просто с железкой работаю, неопытный, даже и не предполагал, что так может быть...

Пример посмотрел спасибо!

vic57 подскажите пожалуйста, каким образом можно избежать данной проблемы, хотя бы куда капнуть?
« Последнее редактирование: Июнь 07, 2018, 21:16 от Harlon » Записан
vic57
Чайник
*
Offline Offline

Сообщений: 90


Просмотр профиля
« Ответ #23 : Июнь 08, 2018, 02:00 »

посылать запрос на следующий пакет только после приема и проверки текущего.
вообще если тебе надо гнать цифру тут tcp и не нужен особо, я на udp делал, проще получается.
а тестировал массивом - гнал массив например 40000 байт, его зеркалил обратно и сравнивал
только я 2 сокета использовал - прием и передачя
Записан
Harlon
Гость
« Ответ #24 : Июнь 08, 2018, 07:58 »

Нашел в документации:

Код
C
while (1) {
if (TcpFastTmrFlag) {
tcp_fasttmr();
TcpFastTmrFlag = 0;
}
if (TcpSlowTmrFlag) {
tcp_slowtmr();
TcpSlowTmrFlag = 0;
}
xemacif_input(netif);
transfer_data();
}
 

The TcpFastTmrFlag and TcpSlowTmrFlag are required for TCP TX handling and are set in the
Timer handler for every 250 ms and 500 ms, respectively.
The function of the application loop is to receive packets constantly (xemacif_input), then
pass them on to lwIP. Before entering this loop, the echo server sets up certain callbacks:...

Получается я начинаю сервер бомбить запросами раз в 5мс, а он на 250 - 500 мс блокируется, неудивительно, что я так обламывался.
Записан
vic57
Чайник
*
Offline Offline

Сообщений: 90


Просмотр профиля
« Ответ #25 : Июнь 08, 2018, 14:07 »

ну это врят ли, скорее через 250-500 мс чего-то там подстраивается. не знаю на чем ты пишешь, я на линухе делал замеры как-то - время реакции ядра на приход данных (poll) - 5 мс. так что обломись сразу  Шокированный реально не менее 10мс депать. быстрее будут тока сборки типа роутеров, это их основная функция.
http://static1.ozone.ru/multimedia/book_file/1003560303.pdf
в этой книге про сокеты неплохо написано 
Записан
Harlon
Гость
« Ответ #26 : Июнь 08, 2018, 20:33 »

У меня не Linux, у меня микропроцессорная система на кристалле, без ОС. http://www.myirtech.com/list.asp?id=565 вот такая штука.
Записан
vic57
Чайник
*
Offline Offline

Сообщений: 90


Просмотр профиля
« Ответ #27 : Июнь 08, 2018, 21:45 »

там arm-linux только IDE под WIN
я имею в виду клиента на чем пишешь
« Последнее редактирование: Июнь 08, 2018, 21:48 от vic57 » Записан
Harlon
Гость
« Ответ #28 : Июнь 08, 2018, 23:12 »

Клиент на QT под виндой, на плате голо, как на коленке. Другая плата разогналась до 200! Победа, тормозила рисовалка. Теперь другая беда, как обойти этот таймер?

Код
C++ (Qt)
void MainWindow::startSending()
{
   // это была попытка запихнуть сокет в поток, кстати без успешная, чет нифига не работало...
   //ascanobj.setA_socket(socket);
   //ascanobj.setrunning(true);
   //thread1.start();
   //это таймер, он работает, но не больше 200-210 запросов в секунду... надо 600    
   ui->startBtn->setEnabled(false);
   ui->stopBtn->setEnabled(true);
   timer.start(ui->speedRecive->value());
}
void MainWindow::stopSending()
{
   //ascanobj.setrunning(false);
 
   ui->stopBtn->setEnabled(false);
   ui->startBtn->setEnabled(true);
   timer.stop();
   /*
   timer_2.stop();
   */

}
 
void MainWindow::sendSocket()
{
   QByteArray getASCAN = 0;
   char ASCAN = 'A';
   getASCAN += ASCAN;
   socket->write(getASCAN);
}
 
« Последнее редактирование: Июнь 08, 2018, 23:25 от Harlon » Записан
vic57
Чайник
*
Offline Offline

Сообщений: 90


Просмотр профиля
« Ответ #29 : Июнь 08, 2018, 23:46 »

как то ты странно пишешь
Код
C++ (Qt)
   socket->write('A');
 
делай краш тест на Си, без таймеров
Код
C
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
 
void error(const char *msg)
{
   perror(msg);
   exit(0);
}
 
int main(int argc, char *argv[])
{
   int sockfd, portno;
   struct sockaddr_in serv_addr;
   struct hostent *server;
 
   char buffer[256];
   if (argc < 3) {
       portno = 8000;
       server = gethostbyname("localhost");
   }
   else {
       portno = atoi(argv[2]);
       server = gethostbyname(argv[1]);
   }
   sockfd = socket(AF_INET, SOCK_STREAM, 0);
   if (sockfd < 0) {
       error("CLI SOCKET");
   }
   if (server == NULL) {
       error("CLI SERVER");
   }
   bzero((char *) &serv_addr, sizeof(serv_addr));
   serv_addr.sin_family = AF_INET;
   bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr,server->h_length);
   serv_addr.sin_port = htons(portno);
   if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0) error("CLI CONNECT");
   while (1) {
       printf("<< ");
       bzero(buffer,256);
       fgets(buffer,255,stdin);
       if (strspn("quit",buffer) == 4) {
           close(sockfd);
           return 0;
       }
       if (send(sockfd,buffer,255,0) < 0) error("CLI WRITE");
       bzero(buffer,256);
       if (recv(sockfd,buffer,255,0) < 0) error("CLI READ");
       fprintf(stderr,">> %s",buffer);
   }
   close(sockfd);
   return 0;
}
 
Записан
Страниц: 1 [2] 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.184 секунд. Запросов: 23.