Запись данных в Tcp socket из другого потока? На однопалатном компьютере работают 2а потока. Первый, Tcp сервер предаёт данные с целевого ПК в UART. Второй проверяет буфер на наличие данных (полинг). UART очень медленный поэтому в одном потоке запустить всё не получается. Необходимо по приходу данных в UART отправить эти данные через Tcp Server на целевой ПК но при вызове метода записи в порт, сервер падает на записи ( socket->write ( data ); ) или даже так не даёт писать в порт ( socket->write ( "data" ); ). Где можно найти документацию или пример для решения этой проблемы? Протокол UART'а ошибка происходит после вызова парсером метода записи myserver.write();void UART_Protokol::ParseCommand() { MyServer myserver; if(sp_dataString == "Start") { TransmitData = "ready"; sp_Send(TransmitData); qDebug()<<"Самопроверка"; } if(sp_dataString == "ready") qDebug()<<"Самопроверка"; if (sp_dataString =="MG1") myserver.write("MG1"); //Например здесь if (sp_dataString =="MG0") myserver.write("MG0"); if (sp_dataString =="MG") qDebug()<listen(QHostAddress::Any,8981))qDebug()<<"Сервер запущен"; else{ qDebug()<setSocketDescriptor( socketDescriptor);// присовение уникального номера порта connect(socket,SIGNAL(readyRead()),this,SLOT(read())); // соединение прерывания порта с методом чтения connect(socket,SIGNAL(disconnected()),this,SLOT(disconect())); //соединение прерывания разрыва соединнинения с методом qDebug()<<socketDescriptor<write("Connection"); } void MyServer::read() { UART_Protokol UART; UART.StartProtokol( false ); arr = socket->readAll(); data += arr; if ( data == "wu" )UART.sp_Send("wu"); if ( data == "su" )UART.sp_Send("su"); if ( data == "au" )UART.sp_Send("au"); if ( data == "du" )UART.sp_Send("du"); if ( data == "qu" )UART.sp_Send("qu"); if ( data == "eu" )UART.sp_Send("eu"); if ( data == "wd" )UART.sp_Send("wd"); if ( data == "sd" )UART.sp_Send("sd"); if ( data == "ad" )UART.sp_Send("ad"); if ( data == "dd" )UART.sp_Send("dd"); if ( data == "qd" )UART.sp_Send("qd"); if ( data == "ed" )UART.sp_Send("ed"); if (data == "SD1")UART.sp_Send("SD1"); if (data == "SD0")UART.sp_Send("SD0"); if (data == "cl")UART.sp_Send("cl"); if( arr[0] == Mask[0]&& arr[1] == Mask[1]) { int length = 0; QByteArray dt = "tr"; trust[0] =0; trust[1] =0; trust[2] =0; length = arr[2]; trust[0] =arr[3]; trust[1] =arr[4]; trust[2] =arr[5]; truster = convert(trust, length - 48); dt[2] = truster; UART.sp_Send_integer(dt); } arr.clear(); //На случай если ошибка длинны появляется из-за неправильной очистки массива. data = ""; } void MyServer::disconect() { socket->deleteLater(); } void MyServer::write (QByteArray dat) {
//Здесь происходит ошибка qDebug()<write(dat); // Так тоже не работает socket->write ("MG1"); } Запуск потоков:#include #include #include #include #include int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); UART_Protokol Serial; Serial.StartProtokol( false ); std::thread serial (&UART_Protokol::Event, Serial); MyServer Server; Server.startserver(); return a.exec(); }
Проблема возникает из-за того, что вы пытаетесь обращаться к сокету из разных потоков, что может вызывать ошибки в работе приложения. Для решения данной проблемы вы можете использовать механизм сигналов и слотов в Qt.
Вы можете сделать следующее:
Измените метод write в MyServer, чтобы он отправлял сигнал с данными, которые нужно записать в сокет.Создайте слот в MyServer, который будет вызываться по сигналу и записывать данные в сокет.В методе ParseCommand класса UART_Protokol вызывайте новый метод, который отправляет сигнал с данными для записи в сокет.
Примерно так:
В классе MyServer добавьте сигнал и слот:signals: void sendDataToSocket(QByteArray data); public slots: void writeToSocket(QByteArray data);Измените метод write в MyServer:void MyServer::write(QByteArray dat) { emit sendDataToSocket(dat); }Создайте слот в MyServer, который будет записывать данные в сокет:void MyServer::writeToSocket(QByteArray data) { socket->write(data); }В методе ParseCommand класса UART_Protokol вызовите новый метод, который отправляет сигнал с данными для записи в сокет:if (sp_dataString == "MG1") emit sendDataToSocket("MG1");
Таким образом, вы будете обращаться к сокету только из основного потока, что должно избавить вас от ошибок. Не забудьте соединить сигнал и слот в конструкторе MyServer:
Проблема возникает из-за того, что вы пытаетесь обращаться к сокету из разных потоков, что может вызывать ошибки в работе приложения. Для решения данной проблемы вы можете использовать механизм сигналов и слотов в Qt.
Вы можете сделать следующее:
Измените метод write в MyServer, чтобы он отправлял сигнал с данными, которые нужно записать в сокет.Создайте слот в MyServer, который будет вызываться по сигналу и записывать данные в сокет.В методе ParseCommand класса UART_Protokol вызывайте новый метод, который отправляет сигнал с данными для записи в сокет.Примерно так:
В классе MyServer добавьте сигнал и слот:signals:void sendDataToSocket(QByteArray data);
public slots:
void writeToSocket(QByteArray data);Измените метод write в MyServer:void MyServer::write(QByteArray dat)
{
emit sendDataToSocket(dat);
}Создайте слот в MyServer, который будет записывать данные в сокет:void MyServer::writeToSocket(QByteArray data)
{
socket->write(data);
}В методе ParseCommand класса UART_Protokol вызовите новый метод, который отправляет сигнал с данными для записи в сокет:if (sp_dataString == "MG1") emit sendDataToSocket("MG1");
Таким образом, вы будете обращаться к сокету только из основного потока, что должно избавить вас от ошибок. Не забудьте соединить сигнал и слот в конструкторе MyServer:
connect(this, &MyServer::sendDataToSocket, this, &MyServer::writeToSocket);Теперь данные будут записываться в сокет из основного потока с использованием механизма сигналов и слотов в Qt.