QTcpSocket:设置LowDelayOption似乎没有效果?

时间:2017-09-16 02:58:05

标签: c++ qt sockets tcp

我有一个Qt GUI应用程序,它使用 QTcpSocket 来发送和接收来自服务器的TCP数据包。到目前为止,我已成功建立TCP套接字连接(有2个独立的套接字连接,因为有2个不同的消息集。两个不同的端口号都有相同的IP地址)以及发送和接收数据包。我的应用程序发送的大多数消息都是通过GUI主窗口上的按钮启动的(一条消息是使用每1667毫秒到期的QTimer定期发送的。)

服务器有一个FIFO(深度为128条消息),并向我的应用程序发送一条特定消息,当FIFO为1/2满,3/4满和满时,该消息进行通信。通过仅仅粘贴GUI上的发送按钮来测试这个功能是很繁琐的,所以我想到了加载一个可以预先填充的.csv文件(消息有几个不同的可配置参数)和我想要的东西发送。每行都被读取并转换为消息并在TCP套接字上发送。

在我的主窗口中,当点击GUI上的按钮时,我打开 QFileDialog 。然后当导航到.csv文件并选择该函数时,一次读取一行.csv文件,拉出所有单独的参数,用参数填充消息,然后将其发送到套接字。每条消息是28个字节。它会重复此操作,直到.csv文件中没有任何行。

我在Wireshark上注意到的是,不是发送一堆单独的TCP数据包,而是将它们放在一起并作为一个大的TCP数据包发送。

当我第一次测试时,我不知道 LowDelayOption ,所以当我在 QAbstractSocket 的文档中找到有关它的信息时,我想" Aha !那一定是它!解决我的问题!"但是当我将它添加到我的代码中时,它似乎根本没有任何影响。它仍然作为一个大型TCP数据包发送。对于每个套接字,我调用 setSocketOption 在插槽函数中将 LowDelayOption 设置为1,该函数从套接字接收 connected()信号。我想也许 setSocketOption 调用没有工作,所以我通过调用 socketOption 来检查这个,以获取 LowDelayOption 的值,它&# 39; s 1。

我还需要做些什么吗?我做错了吗?

感谢您的时间和帮助。如果重要的话我在Windows上开发这个,我使用的是Qt 5.9.1

2 个答案:

答案 0 :(得分:1)

来自QTcpSocket文档:

  

TCP(传输控制协议)是一种可靠的,面向流的,面向连接的传输协议。它特别适用于连续传输数据。

Stream-orientet意味着UDP套接字中没有数据报。 只有数据流,你永远不知道它将被发送到哪个部分。

TCP协议只提供可靠性,您必须自己提供消息提取。即在每条消息之前发送消息长度,或使用QDataStream(检查 例如Fortune serverFortune client



来自QAbstractSocket::SocketOption

LowDelayOption
  

尝试优化套接字以实现低延迟。对于QTcpSocket,这将设置TCP_NODELAY选项并禁用Nagle's algorithm。将其设置为1以启用。   

setsockoptTCP_NODELAY选项相等 首先是:

  

TCP_NODELAY选项特定于TCP / IP服务提供商。

它也不适合我:)


MSDN说他们不建议禁用Nagle的算法:

  

强烈建议TCP / IP服务提供商默认启用Nagle算法,对于绝大多数应用程序协议,Nagle算法可以提供显着的性能增强。但是,对于某些应用程序,此算法可能会影响性能,TCP_NODELAY可用于关闭它。这些是发送许多小消息的应用程序,并且保持消息之间的时间延迟。应用程序编写者不应该设置TCP_NODELAY,除非这样做的影响是很好理解和期望的,因为设置TCP_NODELAY会对网络和应用程序性能产生显着的负面影响。


问题是:您真的需要尽快发送消息吗? 如果是,请考虑使用QUdpSocket。也许告诉我们更多关于你发送的消息。

答案 1 :(得分:1)

  

...向服务器发送和从服务器发送TCP数据包。

由此我得到了你的应用程序依赖于一定数量的数据的氛围 - '数据包'通过一次接听电话接收。

你真的不能依赖它。您通过TCP发送的数据也可能在途中被分段。同样在您的接收端TCP实现中,在您读取第一个数据包之前,可以将从网络接收的多个数据包放入接收套接字缓冲区中,而您无法确定它们最初发送的片段类型。

因此,您应该将TCP视为一个管道,通过该管道,数据字节以一些未知且可能可变的延迟流动。该可变延迟导致数据随机地以更大或更小的块接收。

如果您想拥有数据包结构,则应该将包含至少数据包长度的数据包标头添加到您传输的数据中。

我希望这会有所帮助。