不要从输入队列套接字中读取数据

Posted

技术标签:

【中文标题】不要从输入队列套接字中读取数据【英文标题】:Don't read data from the input queue socket 【发布时间】:2018-09-10 03:59:40 【问题描述】:

我有使用 websocket 的 C++ 程序代码。我使用的服务器端: recv(sSocket, szBufferTmp, 99990, 0) 从客户端接收数据 当客户端发送的数据超过服务器可以读取的速度时,我的服务器在函数 recv() 中被阻塞并且数据仍在输入队列中。我使用 recv(sSocket, szBufferTmp, 99990, MSG_PEEK) 测试并看到我的数据仍在输入队列中。为什么 recv(sSocket, szBufferTmp, 99990, 0) 无法读取数据但 recv(sSocket, szBufferTmp, 99990, MSG_PEEK) 是可能的?我该如何解决? 当客户端发送消息 1、2、3 时,我的错误相同。服务器收到 1,2。客户端发送 4-> 服务器接收 3。 5-> 4,... 尽管数据仍在输入队列中,但它延迟了。我可以通过使用“MSG_PEEK”来获得它 这是我的代码:

Client is javascript: 

> 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. 

服务器:

当(真) recv(sSocket, szBufferTmp, 99990, 0); //recv(sSocket, szBufferTmp, 99990, MSG_PEEK); //一些过程

【问题讨论】:

请在两边显示您的实际代码 客户端是 JavaScript: 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;我使用 m_cWebsocket.send(strMsg) 发送数据。服务器:while (true) recv(sSocket, szBufferTmp, 99990, 0); //recv(sSocket, szBufferTmp, 99990, MSG_PEEK); //某个进程 请edit您的问题包括您的代码。请勿在 cmets 中发布 如果你被recv屏蔽了,那么就没有数据可以读取了。 数据仍在输入队列中,为什么它在recv中被阻止?我该如何解决? 【参考方案1】:

应该是这样的情况,当 send() 发送数据的速度快于 recv() 可以读取时,它会阻塞在 send() 上,直到服务器的 recv() 清除了管道,而不是接收()。

因此,如果您的服务器在客户端速度过快后阻塞了 recv,那么可能发生的情况如下:

Client sending data too fast, but pipe not full yet. Server receiving data.
Pipe fills up. Server->recv getting data. Client->send blocking.
Server->recv gets all the data while Client->send is still blocking.
Pipe empties out. Server->recv blocks until pipe is full again.
    Client->send is still blocking, waiting for a signal to go check if the pipe is ready.

但是,您确实说过输入队列中仍有数据。你没有说你在哪里实现了你提到的 msg_peek,但假设你的仪器实现正确,你的缓冲区“szBufferTmp”是否已满,使用后没有被清除,并且你有一些逻辑阻止它覆盖什么时候满?

需要更多数据来判断是否是这种情况。我们需要查看您的服务器客户端代码,包含您的套接字调用、getaddrinfo 调用和绑定/侦听/接受/连接调用的代码不会有什么坏处,只是为了当然。

【讨论】:

以上是关于不要从输入队列套接字中读取数据的主要内容,如果未能解决你的问题,请参考以下文章

如何使用套接字从服务器读取数据?

使用 BinaryReader/Writer 的 C# Socket 从读取器获取错误数据

从套接字流读取时是不是需要线程睡眠?

没有更多数据可以从套接字错误中读取

Bash读取套接字/ dev / rfcomm0

ORACLE数据连接报错无法从套接字读取更多的数据怎么解决