1

I am creating a network client application that sends requests to a server using a QTcpSocket and expects responses in return. No higher protocol involved (HTTP, etc.), they just exchange somewhat simple custom strings.

In order to test, I have created a TCP server in Python that listens on a socket and logs the strings it receives and those it sends back.

I can send the first request OK and get the expected response. However, when I send the second request, it does not seem to get written to the network.

I have attached debug slots to the QTcpSocket's notification signals, such as bytesWritten(...), connected(), error(), stateChanged(...), etc. and I see the connection being established, the first request sent, the first response processed, the number of bytes written - it all adds up...

Only the second request never seems to get sent :-(

After attempting to send it, the socket sends an error(RemoteHostClosedError) signal followed by ClosingState and UnconnectedState state change signals.

Before I go any deeper into this, a couple of (probably really basic) questions:

  1. do I need to "clear" the underlying socket in any way after reading ?
  2. is it possible / probable that not reading all the data the server has sent me prevents me from writing ?
  3. why does the server close the connection ? Does it always do that so quickly or could that be a sign that something is not right ? I tried setting LowDelay and KeepAlive socket options, but that didn't change anything. I've also checked the socket's state() and isValid() and they're good - although the latter also returns true when unconnected...
  4. In an earlier version of the application, I closed and re-opened the connection before sending a request. This worked ok. I would prefer keeping the connection open though. Is that not a reasonable approach ? What is the 'canonical' way to to implement TCP network communication ? Just read/write or re-open every time ?
  5. Does the way I read from the socket have any impact on how I can write to it ? Most sample code uses readAll(...) to get all available data; I read piece by piece as I need it and << to a QTextStream when writing...

Could this possibly be a bug in the Qt event loop ? I have observed that the output in the Qt Creator console created with QDebug() << ... almost always gets cut short, i.e. just stops. Sometimes some more output is printed when I shut down the application.

This is with the latest Qt 5.4.1 on Mac OS X 10.8, but the issue also occurs on Windows 7.

Update after the first answer and comments:

The test server is dead simple and was taken from the official Python SocketServer.TCPServer Example:

import SocketServer

class MyTCPHandler(SocketServer.StreamRequestHandler):

    def handle(self):
        request  = self.rfile.readline().strip()
        print "RX [%s]: %s" % (self.client_address[0], request)

        response = self.processRequest(request)

        print "TX [%s]: %s" % (self.client_address[0], response)
        self.wfile.write(response)

    def processRequest(self, message):
        if   message == 'request type 01':
            return 'response type 01'
        elif message == 'request type 02':
            return 'response type 02'

if __name__ == "__main__":
    server = SocketServer.TCPServer(('localhost', 12345), MyTCPHandler)
    server.serve_forever()

The output I get is

RX [127.0.0.1]: request type 01
TX [127.0.0.1]: response type 01

Also, nothing happens when I re-send any message after this - which is not surprising as the socket was closed. Guess I'll have to figure out why it is closed...

Next update:

I've captured the network traffic using Wireshark and while all the network stuff doesn't really tell me a lot, I do see the first request and the response. Right after the client [ACK]nowledges the response, the server sends a Connection finish (FIN). I don't see the second request anywhere.

Last update:

I have posted a follow-up question at Python: SocketServer closes TCP connection unexpectedly.

Community
  • 1
  • 1
ssc
  • 9,528
  • 10
  • 64
  • 94
  • remote host (server) is closing your connection - check your server code first – Kamil Klimek Apr 10 '15 at 08:44
  • 1
    Also you should add minimal sample code that reproduces your problem – Kamil Klimek Apr 10 '15 at 08:49
  • "Could this possibly be a bug in the Qt event loop?" The Qt event loop is rather agnostic when it comes to what you apply it for. As far as I can tell, it is bug free in at least Qt 4.7, 5.2 and 5.3, on desktop Windows and on OS X. And that's a rather bold claim to make, so I make it judiciously, given that the code involved in the event loop is thousands of lines long. It's a big feat to have that much code with zero bugs, but that's what seems to be the case. – Kuba hasn't forgotten Monica Apr 10 '15 at 13:45
  • @KubaOber: That was just a wild guess. I never had any issues myself either - but then, logging info in a Qt application also works without a hitch and I thought the observation that the debug output just stops in the middle of a message might be a hint that "something somewhere inside" got stuck... – ssc Apr 10 '15 at 17:53
  • Most likely, the issue is on the other side -- not following the protocol the server expects (which, in this case, is that messages consists of lines). – David Schwartz Apr 10 '15 at 21:44
  • As you can see in the follow-up question, the problem was indeed on the server side. Thanks for your help guys! :-) – ssc Apr 10 '15 at 22:49

1 Answers1

3

Only the second request never seems to get sent :-(

I highly recommend running a program like WireShark and seeing what packets are actually getting sent and received across the network. (As it is, you can't know for sure whether the bug is on the client side or in the server, and that is the first thing you need to figure out)

do I need to "clear" the underlying socket in any way after reading ?

No.

is it possible / probable that not reading all the data the server has sent me prevents me from writing ?

No.

why does the server close the connection ?

It's impossible to say without looking at the server's code.

Does it always do that so quickly or could that be a sign that something is not right ?

Again, this would depend on how the server was written.

This worked ok. I would prefer keeping the connection open though. Is that not a reasonable approach ?

Keeping the connection open is definitely a reasonable approach.

What is the 'canonical' way to to implement TCP network communication ? Just read/write or re-open every time ?

Neither was is canonical; it depends on what you are attempting to accomplish.

Does the way I read from the socket have any impact on how I can write to it ?

No.

Could this possibly be a bug in the Qt event loop ?

That's extremely unlikely. The Qt code has been used for years by tens of thousands of programs, so any bug that serious would almost certainly have been found and fixed long ago. It's much more likely that either there is a bug in your client, or a bug in your server, or a mismatch between how you expect some API call to behave and how it actually behaves.

Jeremy Friesner
  • 70,199
  • 15
  • 131
  • 234
  • Thanks for your response, your advice is really helpful! I will look into WireShark to analyze what actually gets sent and hopefully figure out if the client or the server is the culprit. – ssc Apr 10 '15 at 18:09