c++ - QTcpSocket in a thread doesn't always send data instantly -


i have server handles every client connection in separate thread. test it, implemented simple "echo" service: type message client, sent server, server sends back, , client displays it.

as send short packets, use single write , read current tests, never had split packets.

the client uses write() , readall(), works time (verified packet sniffer tool)

what observe time, server sends packets @ every second occasion.

for example:

  • the client sends "abc"
  • the server receives it, sends back. write() function returns 3.
  • the client receives nothing. check packer sniffer, no packets sent
  • the client sends "def", several seconds, or minutes later
  • the server receives it, sends back. write() function returns 3.
  • the client receives both "abc" , "def" messages. 90% of time 2 separate packets, 10% of time "abcdef".

on rare occasions, 1 message enough. of time, however, second message needed send both first , second message.

an example of client's debug output, indicating sent , received (note client sends typed in manually, , between each message waited @ least 10 seconds):

client: 1 client: 2 server: 1 server: 2 client: 12345 server: 12345 client: abc client: def server: abcdef client: 123 server: 123 client: 456 client: 789 server: 456789 client: server: client: b client: c server: b server: c 

i know tcp 1 continuous stream, wasn't expecting on unburdened lan should take minutes transmit few bytes. interestingly, client can send correctly , instantly, never waits further writes glue them together.

as client seems work perfectly, i'm suspecting wrong threads.

once qtcpserver receives incoming connection, start new thread, passing socketdescriptor thread's constructor.

tcpthread::tcpthread(int socketdescriptor, qobject *parent) : qthread(parent) {     this->socketdescriptor = socketdescriptor; }  void tcpthread::run() {     if (!tcpsocket->setsocketdescriptor(socketdescriptor)) {         qdebug() << tcpsocket->error();         return;     }     connect(tcpsocket, signal(readyread()), this, slot(read_data()));      while (tcpsocket->state() == qabstractsocket::connectedstate)     {         tcpsocket->waitfordisconnected(-1);     } }   void tcpthread::read_data() {     qbytearray data = tcpsocket->readall();      int nr = tcpsocket->write(data);     qdebug() << data << " (" << nr << " bytes written)"; } 

i know, not best practice of handling threads, used "qt4 approach" quick familiarization qtcpsocket.

what interesting, receive warnings @ each call write():

qsocketnotifier: socket notifiers cannot enabled or disabled thread

i wonder why. created instance of qtcpsocket in run() method of thread, should in same thread, shouldn't it?

indeed, if move instantiation of socket constructor, get

qobject: cannot create children parent in different thread. (parent qtcpsocket(0x2c54a80), parent's thread qthread(0x10776d0), current thread tcpthread(0x2c53c18)

which didn't before. however, instantiation in constructor, code works same: message sent instantly, glued , sent next message, no matter how time passes between two.

what doing wrong?

using thread qtcpsocket s pointless. asynchronous api gain using thread minimal (problem may when have other time consuming job blocks event loop).

another problem way creating objects , assign them threads. you've given perfect link topic didn't understand it.

simple rules when using threads in qt:

  • never assign thread itself
  • you can move objects between threads if don't have parent (it root of memory structure tree, whole 3 moved new thread)
  • setting parent assigns object parent thread
  • default connections of slots , signals detects signal emitted different thread receiver assigned to, in such case signal wrapped , passed proper thread using event loop.
  • if using value objects in signal slots don't need synchronization (locks , mutexes)
  • when override qthread::run() , using signals , slots should run event loop in thread, either calling qthread::exec() or creating new event loop.

so in general have lots of mistakes in code. recomand abandon qthread or @ least read article again understand , apply recommendations (it written before qt5 released, claim "qt4 style" invalid).


Comments

Popular posts from this blog

java - Date formats difference between yyyy-MM-dd'T'HH:mm:ss and yyyy-MM-dd'T'HH:mm:ssXXX -

c# - Get rid of xmlns attribute when adding node to existing xml -