Запись данных в 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();
}

21 Авг 2019 в 06:37
241 +1
0
Ответы
1

Проблема возникает из-за того, что вы пытаетесь обращаться к сокету из разных потоков, что может вызывать ошибки в работе приложения. Для решения данной проблемы вы можете использовать механизм сигналов и слотов в 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.

20 Апр 2024 в 13:15
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Гарантированные бесплатные доработки в течение 1 года
Быстрое выполнение от 2 часов
Проверка работы на плагиат
Поможем написать учебную работу
Прямой эфир