C++/Qt:QTcpSocket 读取后不会写入
C++/Qt: QTcpSocket won't write after reading
我正在创建一个网络客户端应用程序,它使用 QTcpSocket 向服务器发送请求并期望在 return 中得到响应。不涉及更高的协议(HTTP 等),它们只是交换一些简单的自定义字符串。
为了测试,我在 Python 中创建了一个 TCP 服务器,它侦听套接字并记录它接收到的字符串和发回的字符串。
我可以发送第一个请求并获得预期的响应。但是,当我发送第二个请求时,它似乎没有写入网络。
我已将调试槽附加到 QTcpSocket
的通知信号,例如 bytesWritten(...)
、connected()
、error()
、stateChanged(...)
等。我看到正在建立的连接、发送的第一个请求、处理的第一个响应、写入的字节数 - 所有这些加起来...
只有第二个请求似乎从未发送过:-(
尝试发送后,套接字发送一个 error(RemoteHostClosedError)
信号,然后是 ClosingState
和 UnconnectedState
状态更改信号。
在我深入探讨之前,先问几个(可能非常基本的)问题:
- 我是否需要在阅读后以任何方式"clear"底层套接字?
- 有没有可能/很可能没有读取服务器发送给我的所有数据会阻止我写入?
- 为什么服务器会关闭连接?它总是那么快地这样做吗?或者这可能是某事不对劲的迹象?我尝试设置
LowDelay
和 KeepAlive
套接字选项,但这并没有改变任何东西。我还检查了套接字的 state()
和 isValid()
,它们很好 - 尽管后者在未连接时也 returns true
...
- 在早期版本的应用程序中,我在发送请求之前关闭并重新打开了连接。这工作正常。不过,我更愿意保持连接打开。这不是一个合理的做法吗? 'canonical'实现TCP网络通信的方法是什么?只是 read/write 还是每次都重新打开?
- 我从套接字读取的方式对我如何写入有任何影响吗?大多数示例代码使用
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)
。我在任何地方都没有看到第二个请求。
最后更新:
我已经在 上发布了后续问题。
Only the second request never seems to get sent :-(
我强烈推荐 运行 像 WireShark 这样的程序,它可以查看网络上实际发送和接收的数据包。 (事实上,你不能确定这个bug是在客户端还是在服务器端,这是你首先要搞清楚的)
do I need to "clear" the underlying socket in any way after reading ?
没有
is it possible / probable that not reading all the data the server has
sent me prevents me from writing ?
没有
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 ?
同样,这取决于服务器的编写方式。
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 ?
两者都不是规范的;这取决于您要完成的任务。
Does the way I read from the socket have any impact on how I can write
to it ?
没有
Could this possibly be a bug in the Qt event loop ?
这极不可能。 Qt 代码已被数以万计的程序使用多年,因此任何严重的错误几乎肯定早就被发现并修复了。更有可能是您的客户端中存在错误,或者您的服务器中存在错误,或者您期望某些 API 调用的行为方式与实际行为方式不匹配。
我正在创建一个网络客户端应用程序,它使用 QTcpSocket 向服务器发送请求并期望在 return 中得到响应。不涉及更高的协议(HTTP 等),它们只是交换一些简单的自定义字符串。
为了测试,我在 Python 中创建了一个 TCP 服务器,它侦听套接字并记录它接收到的字符串和发回的字符串。
我可以发送第一个请求并获得预期的响应。但是,当我发送第二个请求时,它似乎没有写入网络。
我已将调试槽附加到 QTcpSocket
的通知信号,例如 bytesWritten(...)
、connected()
、error()
、stateChanged(...)
等。我看到正在建立的连接、发送的第一个请求、处理的第一个响应、写入的字节数 - 所有这些加起来...
只有第二个请求似乎从未发送过:-(
尝试发送后,套接字发送一个 error(RemoteHostClosedError)
信号,然后是 ClosingState
和 UnconnectedState
状态更改信号。
在我深入探讨之前,先问几个(可能非常基本的)问题:
- 我是否需要在阅读后以任何方式"clear"底层套接字?
- 有没有可能/很可能没有读取服务器发送给我的所有数据会阻止我写入?
- 为什么服务器会关闭连接?它总是那么快地这样做吗?或者这可能是某事不对劲的迹象?我尝试设置
LowDelay
和KeepAlive
套接字选项,但这并没有改变任何东西。我还检查了套接字的state()
和isValid()
,它们很好 - 尽管后者在未连接时也 returnstrue
... - 在早期版本的应用程序中,我在发送请求之前关闭并重新打开了连接。这工作正常。不过,我更愿意保持连接打开。这不是一个合理的做法吗? 'canonical'实现TCP网络通信的方法是什么?只是 read/write 还是每次都重新打开?
- 我从套接字读取的方式对我如何写入有任何影响吗?大多数示例代码使用
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)
。我在任何地方都没有看到第二个请求。
最后更新:
我已经在
Only the second request never seems to get sent :-(
我强烈推荐 运行 像 WireShark 这样的程序,它可以查看网络上实际发送和接收的数据包。 (事实上,你不能确定这个bug是在客户端还是在服务器端,这是你首先要搞清楚的)
do I need to "clear" the underlying socket in any way after reading ?
没有
is it possible / probable that not reading all the data the server has sent me prevents me from writing ?
没有
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 ?
同样,这取决于服务器的编写方式。
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 ?
两者都不是规范的;这取决于您要完成的任务。
Does the way I read from the socket have any impact on how I can write to it ?
没有
Could this possibly be a bug in the Qt event loop ?
这极不可能。 Qt 代码已被数以万计的程序使用多年,因此任何严重的错误几乎肯定早就被发现并修复了。更有可能是您的客户端中存在错误,或者您的服务器中存在错误,或者您期望某些 API 调用的行为方式与实际行为方式不匹配。