Reputation: 1022
I am making a simple program that will 'connect' to itself and then send data. It starts a QTcpServer then waits for any incoming connections. I have a separate function that will in turn attempt to connect to this server at the localhost and port I decided on. This works when I open Telnet in the command prompt, but now in my actual program. Here is the code that I used (Some are snippets from other sources)
MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
server = new QTcpServer(this);
//Initialize and start the server
connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
if (!server->listen(QHostAddress::Any, 3665))
{
qDebug() << "Server failed to start!";
}
else
{
qDebug() << "Server started";
}
//Try to connect to the server
connectToServer("127.0.0.1", qint16(3665));
}
MainWindow::~MainWindow()
{
delete server;
delete ui;
}
void MainWindow::connectToServer(QString host, qint16 port)
{
qDebug() << "Connecting to " + host + " at port " + QString::number(port);
QTcpSocket socket;
socket.connectToHost(host, port);
if (!socket.waitForConnected(5000))
{
qDebug() << socket.errorString();
}
while (socket.bytesAvailable() < (int)sizeof(quint16))
{
if (!socket.waitForReadyRead(5000))
{
qDebug() << socket.errorString();
}
}
quint16 blockSize;
QDataStream in(&socket);
in.setVersion(QDataStream::Qt_5_5);
in >> blockSize;
while (socket.bytesAvailable() < blockSize)
{
if (!socket.waitForReadyRead(5000))
{
qDebug() << socket.errorString();
}
}
QString fortune;
in >> fortune;
qDebug() << fortune;
}
void MainWindow::newConnection()
{
qDebug() << "A connection has been found.";
QTcpSocket *socket = server->nextPendingConnection();
socket->write("hello client\r\n");
socket->flush();
socket->waitForBytesWritten(5000);
socket->close();
}
Upvotes: 1
Views: 416
Reputation: 98425
The source of your problem is, most likely, the pseudo-synchronous mess caused by waitFor
methods. Get rid of them. Furthermore, you're not guaranteed anything about how many bytes you receive upon readyRead
: it's perfectly normal to receive one byte at a time, in some circumstances, or really any number of bytes, including more bytes than you might expect. Your code must cope with that.
This is one example of such approach - it does what you want, asynchronously. That is another example that shows how to leverage state machines to write asynchronous communications code using an easy to read, declarative syntax.
Upvotes: 2