我正在创建一个网络客户端应用程序,它使用QTcpSocket向服务器发送请求,并期望得到响应。没有更高的协议(HTTP等),他们只是交换一些简单的自定义字符串。
为了测试,我在Python中创建了一个TCP服务器,它监听套接字并记录它收到的字符串和它发回的字符串。
我可以发送第一个请求,然后获得预期的响应。但是,当我发送第二个请求时,似乎没有写入网络。
我已将调试位置附加到QTcpSocket
的通知信号,例如bytesWritten(...)
,connected()
,error()
,stateChanged(...)
等我看到建立连接,发送第一个请求,处理第一个响应,写入的字节数 - 这一切都加起来......
似乎永远不会发送第二个请求: - (
尝试发送后,套接字发送error(RemoteHostClosedError)
信号,然后发出ClosingState
和UnconnectedState
状态更改信号。
在我深入研究这个问题之前,有几个(可能是非常基本的)问题:
LowDelay
和KeepAlive
套接字选项,但这并没有改变任何内容。我还检查了套接字state()
和isValid()
并且它们很好 - 虽然后者在未连接时也会返回true
... readAll(...)
来获取所有可用数据;我在需要时逐段阅读,在写作时<<
阅读QTextStream ... 这可能是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发布了一个跟进问题。
答案 0 :(得分:3)
似乎永远不会发送第二个请求: - (
我强烈建议运行像WireShark这样的程序,看看实际上通过网络发送和接收的数据包。 (实际上,您无法确定该错误是在客户端还是在服务器中,这是您需要弄清楚的第一件事)
读完后我是否需要以任何方式“清除”底层套接字?
没有
是否可能/不可能读取服务器拥有的所有数据 发给我阻止我写作?
没有
为什么服务器会关闭连接?
如果不查看服务器的代码,就不可能说。
它是否总能这么快地完成,或者这可能是一个标志 有些事情不对吗?
同样,这取决于服务器的编写方式。
这工作正常。我宁愿保持连接打开。是 那不合理吗?
保持连接打开绝对是一种合理的方法。
实施TCP网络通信的“规范”方法是什么? ?只是每次读/写或重新打开?
两者都不是规范的;这取决于你想要完成的事情。
我从套接字读取的方式是否会影响我的编写方式 对吗?
没有
这可能是Qt事件循环中的错误吗?
这是极不可能的。 Qt代码已被成千上万的程序使用多年,因此任何严重的错误几乎肯定会在很久以前找到并修复。您的客户端中存在错误或服务器中存在错误,或者您希望某些API调用的行为方式与实际行为之间存在不匹配的可能性更大。