Qt QTcpSocket的write无法发送数据【已解决】
Qt QTcpSocket的write无法发送数据
- 一、问题描述
- 二、解决方案
- 三、深入了解write机制
- 3.1 write函数
- 3.2 flush函数
- 3.3 waitForBytesWritten函数
- 四、参考链接
一、问题描述
QTcpSocket的write函数发送数据,使用网络调试助手收不到值,但能收到连接和断开连接,单步Debug write函数能执行成功,也有返回值。使用wireshark抓包,只有连接和断开连接的信号,没有数据发来。
也怀疑缓冲区不够就不发,write了很多也没用,感觉像是哪里堵塞或者缓冲区有问题,尝试停了其它QTcpSocket,只留一个点击按钮才发送,能正常发。
网上搜了也有很多类似的问题,官方文档并没有写清楚它的机制。
二、解决方案
综合网上的回答与自己的测试结果,主要有以下两种解决方案:
-
- write后,立即使用flush 或 waitForBytesWritten (
可能会带来性能上的问题
)
- write后,立即使用flush 或 waitForBytesWritten (
-
- 使用信号和槽,槽函数里调用write (
交给Qt,比较推荐
)
(死去的回忆攻击了我,之前就是这么写的,所以没有发现这个问题,也就没有深入了解)
- 使用信号和槽,槽函数里调用write (
三、深入了解write机制
3.1 write函数
QTcpSocket的write是非阻塞式的,它会写入内部缓冲区, 并不会发送出去。其发送依赖于事件循环,或者底层的网络协议和系统调度 - 具体可深入源码了解。
借用论坛中大佬的回复:
write的频率过高则会将数据全部写入缓冲区,测试的时候大概估计100
微妙以上的间隔才会发送,要不会一直写缓存。
3.2 flush函数
bool QAbstractSocket::flush ()
调用flush
,会将内部写缓冲区写入底层socket,而不会造成阻塞。只要有数据写入就返回true;否则返回false。需要立即发送缓冲区的数据,可以调用此函数,成功写入的字节数取决于操作系统
。
一般不需要调用此函数,一旦返回事件循环,QAbstractSocket将自动开始发送数据。在没有事件循环的情况下,改为调用waitForBytesWriten()。
3.3 waitForBytesWritten函数
bool QAbstractSocket::waitForBytesWritten ( int msecs = 30000 )
调用此函数会阻塞,直到缓冲的数据已写入设备并发出bytesWriten()信号,或者超时 (默认)。如果msecs为-1,则此函数不会超时。如果数据已写入设备,则返回true;否则返回false(超时或发生错误)。
应用于非GUI应用程序
和在非GUI线程中
执行I/O操作时,即用最好新线程使用此函数,避免阻塞。
注:此函数在windows上有bug,建议使用事件循环或
bytesWritten()
信号
四、参考链接
- QT QTcpSocket发送数据问题:https://blog.csdn.net/soulfy/article/details/19631735
- 如何在QTCPSocket中不使用flush和waitFOrBytesWritten将数据直接写入套接字:https://cloud.tencent.com/developer/ask/sof/104559805
- Qt中的QTcpSocket类的write()方法不能发送数据的解决方法:https://blog.csdn.net/simmerlee/article/details/9000882
- QT中QTcpSocket的write函数问题:https://bbs.csdn.net/topics/390411733
- QTcpSocket通信编程时阻塞与非阻塞的问题:https://blog.csdn.net/NEOMc/article/details/5548959
- 使用Qtcpsocket中的flush()方法后导致release版本运行不稳定问题:https://bbs.csdn.net/topics/390982307