Двунаправленный клиентский сервер Qt с использованием QTcpSocket и QTcpServer
Я пытаюсь реализовать двунаправленную программу клиент-сервер, где клиенты и серверы могут передавать сериализованные объекты друг другу. Я пытаюсь сделать это с помощью Qt (QTcpSocket и QTcpServer). Я реализовал такие программы на java, но я не могу понять, как это сделать с помощью Qt. Я проверил клиент удачи и сервер удачи примеры...но из того, что я вижу, клиент просто сигнализирует серверу, и сервер отправляет его некоторые данные. Мне нужно, чтобы клиент и сервер отправляли объекты туда и обратно. Я не ищу полного решения, все, что я ищу, это некоторое руководство в правильном направлении.
Я написал код, который принимает соединение, но не принимает данные.
сервер
этот класс является сервером; он должен принимать соединение и выводить размер буфера, который отправляется. Однако он выводит 0
#include "comms.h"
Comms::Comms(QString hostIP, quint16 hostPort)
{
server = new QTcpServer(this);
hostAddress.setAddress(hostIP);
this->hostPort = hostPort;
}
void Comms::attemptConnection(){
connect(server, SIGNAL(newConnection()), this, SLOT(connectionAccepted()));
//socket = server->nextPendingConnection();
server->listen(hostAddress,hostPort);
//receivedData = socket->readAll();
}
void Comms::connectionAccepted(){
qDebug()<<"Connected";
socket = new QTcpSocket(server->nextPendingConnection());
char* rec = new char[socket->readBufferSize()];
qDebug()<<socket->readBufferSize();
}
клиент
этот класс является клиент. Он должен отправлять строку "hello". Он отправляет его успешно (насколько мне известно)
#include "toplevelcomms.h"
#include "stdio.h"
TopLevelComms::TopLevelComms(QString hostIP, quint16 hostPort)
{
tcpSocket = new QTcpSocket();
hostAddress.setAddress(hostIP);
this->hostPort = hostPort;
}
void TopLevelComms::connect(){
tcpSocket->connectToHost(hostAddress,hostPort,QIODevice::ReadWrite);
//tcpSocket->waitForConnected(1);
QString string = "Hello";
QByteArray array;
array.append(string);
qDebug()<<tcpSocket->write(array);
}
2 ответов
QTcpSocket по умолчанию асинхронен, поэтому при вызове connectToHost и записи в том же контексте он не будет отправлен, так как сокет не подключен. Вы должны изменить свой" клиентский " код:
void TopLevelComms::connect(){
tcpSocket->connectToHost(hostAddress,hostPort,QIODevice::ReadWrite);
if(tcpSocket->waitForConnected()) // putting 1 as parameter isn't reasonable, using default 3000ms value
{
QString string = "Hello";
QByteArray array;
array.append(string);
qDebug()<<tcpSocket->write(array);
}
else
{
qDebug() << "couldn't connect";
}
}
Примечание: Вы также не проверили, можете ли вы слушать
void Comms::attemptConnection(){
connect(server, SIGNAL(newConnection()), this, SLOT(connectionAccepted()));
//socket = server->nextPendingConnection();
if(server->listen(hostAddress,hostPort))
{
qDebug() << "Server listening";
}
else
{
qDebug() << "Couldn't listen to port" << server->serverPort() << ":" << server->errorString();
}
//receivedData = socket->readAll();
}
и последнее. Обратите внимание, что QTcpServer:: nextPendingConnection () возвращает QTcpSocket, поэтому вместо того, чтобы принимать это новое соединение, вы создаете новый QTcpSocket с nextPendingConnection как родитель!--5-->
void Comms::connectionAccepted(){
qDebug()<<"Connected";
// WRONG! it will use QTcpSocket::QTcpSocket(QObject * parent)
//socket = new QTcpSocket(server->nextPendingConnection());
// use simple asign
socket = server->nextPendingConnection();
// move reading to slot
connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket()));
}
теперь мы переместим чтение в отдельный слот
void Comms::readSocket()
{
// note that dynamic size array is incompatible with some compilers
// we will use Qt data structure for that
//char* rec = new char[socket->readBufferSize()];
qDebug()<<socket->readBufferSize();
// note that QByteArray can be casted to char * and const char *
QByteArray data = socket->readAll();
}
Я должен признать, что это много ошибок, как для такого небольшого образца кода. Вам нужно получить некоторые знания о соединениях TCP / IP. Это потоки, и нет никакой гарантии, что весь кусок данных попадет к вам сразу
похоже, у вас проблемы со временем. Поскольку ваш клиент и сервер-это разные процессы, вы не можете гарантировать, что вся TopLevelComms::connect()
выполняется (вместе с передачей сетевых данных) передconnectionAccepted()
функция пытается читать из сокета.
Я подозреваю, что если вы воспользуетесь QTcpSocket в waitForReadyRead() функция, вы должны иметь больше удачи:
void Comms::connectionAccepted(){
qDebug()<<"Connected";
socket = new QTcpSocket(server->nextPendingConnection());
if( socket->waitForReadyRead() ) {
char* rec = new char[socket->readBufferSize()];
qDebug()<<socket->readBufferSize();
}
}