C ++ / Qt:QTcpSocket读后不会写

时间:2015-04-09 22:05:06

标签: c++ qt sockets tcp network-programming

我正在创建一个网络客户端应用程序,它使用QTcpSocket向服务器发送请求,并期望得到响应。没有更高的协议(HTTP等),他们只是交换一些简单的自定义字符串。

为了测试,我在Python中创建了一个TCP服务器,它监听套接字并记录它收到的字符串和它发回的字符串。

我可以发送第一个请求,然后获得预期的响应。但是,当我发送第二个请求时,似乎没有写入网络。

我已将调试位置附加到QTcpSocket的通知信号,例如bytesWritten(...)connected()error()stateChanged(...)等我看到建立连接,发送第一个请求,处理第一个响应,写入的字节数 - 这一切都加起来......

似乎永远不会发送第二个请求: - (

尝试发送后,套接字发送error(RemoteHostClosedError)信号,然后发出ClosingStateUnconnectedState状态更改信号。

在我深入研究这个问题之前,有几个(可能是非常基本的)问题:

  1. 我需要"清除"阅读之后的任何方式的底层套接字?
  2. 是否可能/可能不读取服务器发给我的所有数据会阻止我写作?
  3. 为什么服务器会关闭连接?它总是如此迅速地做到这一点,还是表明事情不对?我尝试设置LowDelayKeepAlive套接字选项,但这并没有改变任何内容。我还检查了套接字state()isValid()并且它们很好 - 虽然后者在未连接时也会返回true ...
  4. 在早期版本的应用程序中,我在发送请求之前关闭并重新打开了连接。这工作正常。我宁愿保持连接打开。这不是一个合理的方法吗?什么是'规范'实现TCP网络通信的方法?每次只读/写或重新打开?
  5. 我从套接字读取的方式对我如何写入它有什么影响吗?大多数示例代码使用readAll(...)来获取所有可用数据;我在需要时逐段阅读,在写作时<<阅读QTextStream ...
  6. 这可能是Qt事件循环中的错误吗?我观察到用QDebug() << ...创建的Qt Creator控制台中的输出几乎总是被缩短,即停止。当我关闭应用程序时,有时会打印更多输出。

    这是Mac OS X 10.8上最新的Qt 5.4.1,但问题也发生在Windows 7上。

    在第一个回答和评论后更新:

    测试服务器很简单,取自官方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()
    

    我得到的输出是

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

    此外,当我在此之后重新发送任何消息时没有任何反应 - 这在套接字关闭时并不奇怪。猜猜我必须找出为什么关闭......

    下次更新:

    我使用Wireshark捕获了网络流量,虽然所有的网络内容并没有真正告诉我很多,但我确实看到了第一个请求和响应。在客户端[ACK]现在响应后,服务器发送Connection finish (FIN)。我在任何地方都没有看到第二个请求。

    上次更新:

    我已在Python: SocketServer closes TCP connection unexpectedly发布了一个跟进问题。

1 个答案:

答案 0 :(得分:3)

  

似乎永远不会发送第二个请求: - (

我强烈建议运行像WireShark这样的程序,看看实际上通过网络发送和接收的数据包。 (实际上,您无法确定该错误是在客户端还是在服务器中,这是您需要弄清楚的第一件事)

  

读完后我是否需要以任何方式“清除”底层套接字?

没有

  

是否可能/不可能读取服务器拥有的所有数据   发给我阻止我写作?

没有

  

为什么服务器会关闭连接?

如果不查看服务器的代码,就不可能说。

  

它是否总能这么快地完成,或者这可能是一个标志   有些事情不对吗?

同样,这取决于服务器的编写方式。

  

这工作正常。我宁愿保持连接打开。是   那不合理吗?

保持连接打开绝对是一种合理的方法。

  

实施TCP网络通信的“规范”方法是什么?   ?只是每次读/写或重新打开?

两者都不是规范的;这取决于你想要完成的事情。

  

我从套接字读取的方式是否会影响我的编写方式   对吗?

没有

  

这可能是Qt事件循环中的错误吗?

这是极不可能的。 Qt代码已被成千上万的程序使用多年,因此任何严重的错误几乎肯定会在很久以前找到并修复。您的客户端中存在错误或服务器中存在错误,或者您希望某些API调用的行为方式与实际行为之间存在不匹配的可能性更大。