使用网络套接字时,邮件被延迟

时间:2018-08-27 04:42:03

标签: javascript c++ sockets websocket

我有一个使用 Websocket TCP 的程序:客户端是Chrome中的扩展程序,服务器是用C ++编写的应用程序。
当我从clientserver发送小数据时,它可以正常工作。但是,当我发送大量数据(例如源HTML页面)时,它会稍有延迟。


例如:

  • 客户发送: 1,2,3
    • 服务器收到: 1,2
  • 客户发送: 4
    • 服务器收到: 3
  • 客户发送: 5
    • 服务器收到: 4

这似乎是一个延迟。

  1. 这是我的代码客户端:

var m_cWebsocket = new WebSocket("Servername"); 
if (m_cWebsocket == null) { return false; } 
m_cWebsocket.onopen = onWebsocketOpen(m_cWebsocket); m_cWebsocket.onmessage = onWebsocketMessage; 
m_cWebsocket.onerror = onWebsocketError; 
m_cWebsocket.onclose = onWebsocketError; 
I using m_cWebsocket.send(strMsg) to send data. 

  1. 服务器代码
  

while(true){recv(sSocket,szBufferTmp,99990,0); // recv(sSocket,   szBufferTmp,99090,MSG_PEEK); //一些过程}

1 个答案:

答案 0 :(得分:1)

由于您还没有发布任何代码来显示TCP服务器或客户端的实现,所以我只能推测并尝试解释此处可能发生的

这意味着我在下面概述的潜在问题和解决方案可能适用于您,也可能不适用于您,但是无论这些信息仍然对将来可能会遇到此问题的其他人有所帮助。


TL; DR :(最有可能)是服务器太慢,服务器未正确等待完整的“ tcp数据包”被缓冲,或者服务器不知道何时正确启动和停止,并在等待它认为是像缓冲区大小之类的“完整数据包”时取消同步。

在我看来,您正在以比服务器可以读取的服务器更快的速度从客户端推送数据,或者更有可能是服务器正在从当前TCP Stream缓冲一定数量的字节并等待在输出其他数据之前先填充缓冲区。

如果您是通过localhost发送此消息,则不太可能达到接近流的限制,我希望用C ++编写的服务器能够跟上javascript客户端的速度。

因此,这使我相信问题实际上是C ++端的流缓冲区。

现在,由于服务器无法知道正在发送的数据以及正在发送的数据量,因此TCP流通常使用流缓冲区从套接字连续读取数据,直到出现以下情况为止:缓冲区已填充到已知大小,或者直到它看到预定义的“停止字符”为止。这通常类似于“换行符”或\n字符,有时取决于操作系统,\n\r(换行符,回车符)。

由于您尚未指定如何接收数据,因此我假设您创建了某个大小的charbyte缓冲区。我对我的C ++套接字信息非常生疏,所以我可能错了,但是我相信C ++ tcp流上也存在默认的“读取超时”。

这意味着您可能会遇到2个问题之一。

情况1)您正在等待byte / char缓冲区被填充,然后再输出其数据。问题是,它将像只在所有座位都坐满时才离开车站的公共汽车一样。如果您没有坐满席位,则服务器只是在等待并等待直到获得更多数据以完全填满并输出数据。

情况2)您正在经历套接字读取超时,因此该函数在输出数据之前未获取所有数据。这就像按时间运行的总线。公交车每离开车站10分钟,无论公交车是满还是空,都将离开,下一班公共汽车将接载迟到的任何人。在您的情况下,TCP流无法足够快地将1, 2 and 3加载到总线上,因此总线仅留下1, 2就离开了,因为在20毫秒未接收到数据之后,服务器正从函数并输出数据。但是,在下一个循环中,3等待在流缓冲区的顶部,准备好进入下一个总线。流将加载3,等待直到20ms完成,然后退出,然后重复此循环。

我认为第一种情况很有可能发生,因为我希望服务器要么开始赶上,要么随着两台服务器开始同步在一起或者在内部TPC流缓冲区填满而进一步落后服务器越来越落后。

这里要点,您需要某种方式来同步客户端和服务器连接。我建议在消息开始和结束时向单个发送“开始字节”和“结束字节”,因此不要过早退出该功能。
或发送一个开始字节,然后是数据包大小(以字节为单位),然后填满缓冲区,直到缓冲区中的字节数正确为止。此外,您还可以包括一个结束字节,以进行一些基本的错误检查。

这是一个涉及很深的话题,很难在没有任何代码的情况下给您一个很好的答案,但是这也应该会在将来帮助任何可能遇到类似问题的人。

编辑,我回过头来重新阅读了您的问题,发现您说的只是大量数据,所以我认为我最初的假设是错误的,并且更可能是情况2 ,因为客户端向服务器发送数据的速度比服务器读取数据的速度快,因此可能会造成连接瓶颈,并且客户端只能在服务器已清空部分TCP流缓冲区。

想起来就像一桶水。插座(管)只能在充满之前接受(填满)这么多的数据(水)。但是,一旦将水倒出底部,您可以再加一点。它适用于小文件的唯一原因是文件太小而无法填满整个试管。

其他想法:您可以在以下问题中看到我如何在C#中解决此问题:Continuously reading from serial port asynchronously properly

还有我之前(也是在C#中)遇到的另一个类似问题:How to use Task.WhenAny with ReadLineAsync to get data from any TcpClient

自从我开始使用TCP流以来已经有一段时间了,所以我的道歉我不记得协议的所有利基细节和警告,但是希望此信息足以使您了解解决您的问题。


完全免责声明,自从我上次接触C ++ TCP套接字以来已经有两年多了,并且自从使用其他语言(例如C#和JavaScript)的套接字/ Websocket开始工作以来,所以我可能对C ++的行为有误解特别是TCP套接字,但是核心信息仍然适用。如果我有任何问题,评论中的某人很可能会获得正确的信息。

最后,欢迎堆栈溢出!