Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why QTcpSocket doesn't write ? I need to flush it to make it send my data

Tags:

c++

sockets

qt

I read in the documentation that to send a packet with QTcpSocket I can just use the write method. But when I do it, my server doesn't receive it. I need to call flush or waitForByteWritten to send it.

TCPClient::TCPClient(Client *babel , const std::string &hostname, unsigned short port, QObject *parent) : QObject(parent), client(babel),  hostName(hostname), port(port), is_connected(false)
{
  this->tcpSocket = new QTcpSocket(this);
  connect(this->tcpSocket, SIGNAL(readyRead()),this, SLOT(readMessage()));
  connect(this->tcpSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(displayError(QAbstractSocket::SocketError)));
  connect(this->tcpSocket, SIGNAL(connected()), this, SLOT(connectReady()));
  connect(this->tcpSocket, SIGNAL(disconnected()), this, SLOT(disconnectedReady()));

}

TCPClient::~TCPClient()
{

}

bool TCPClient::initiateService()
{
  this->tcpSocket->connectToHost(this->hostName.c_str(), this->port);
  this->tcpSocket->waitForConnected(5000);
}

void TCPClient::connectReady()
{
  this->is_connected = true;
}

void TCPClient::disconnectedReady()
{

}


bool TCPClient::sendBabelPacket(Protocol::BabelPacket &packet)
{
  if(this->tcpSocket->state() == QAbstractSocket::ConnectedState && is_connected)
  {
    std::cout << "writing ... size : " << sizeof(Protocol::BabelPacket) + packet.dataLength<<std::endl;
    this->tcpSocket->write((const char *)&packet, sizeof(Protocol::BabelPacket) + packet.dataLength);
    //this->tcpSocket->flush();
    return true;
  }
  else
  {
    std::cout << "socket close" << std::endl;
    return false;
  }
}


void TCPClient::shutDown()
{
  this->tcpSocket->abort();
}

void TCPClient::displayError(QAbstractSocket::SocketError socketError)
{

}

void TCPClient::readMessage()
{
  char buffer[sizeof(Protocol::BabelPacket)];
  this->tcpSocket->read(buffer, sizeof(Protocol::BabelPacket));
}

When I call write, it returns the right amount of bytes.

I use this class in a GUI context, in the same thread.

like image 219
Dimitri Danilov Avatar asked Jan 05 '23 02:01

Dimitri Danilov


1 Answers

QTcpSocket is a buffered device, so data is not written directly, but into internal buffer. Documentation states:

Note: TCP sockets cannot be opened in QIODevice::Unbuffered mode.

Because of it you should call flush or waitForBytesWritten to be sure something is transferred.

There is the difference between them. flush writes as much as possible from the internal write buffer to the underlying network socket, without blocking. waitForBytesWritten blocks until at least one byte has been written on the socket and the bytesWritten() signal has been emitted.

like image 179
Nikita Avatar answered Jan 07 '23 14:01

Nikita