我在进程连接上使用Net::SocketReactor。当数据输入到套接字时,调用了类似以下代码的东西:
int WebSocketWrapper::DoRecieve(void *buf) {
try{
int flags;
const auto size = m_sock.availabel();
const auto ret = m_sock.receiveFrame(buf, size, flags);
if (size != ret){
logger.warrning('Read less than available');
}
return ret;
}
catch (WebSocketException& exc){
logger.log(exc);
switch (exc.code()){
case pnet::WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
logger.debug("unsuported version");
break;
// fallthrough
case pnet::WebSocket::WS_ERR_NO_HANDSHAKE:
case pnet::WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
case pnet::WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
logger.debug("Bad request");
break;
}
}
return 0;
}
当数据大小小于1400字节时,这是很好的工作方式。TCP包未分段。但当我尝试发送超过1400字节的数据时,我会遇到WebSocketException:"缓冲区不足,无法容纳负载大小"。我正在研究源代码Poco::Net::Websocket,他发现了冲突。当调用Websocket::readFrame时,会分析帧的大小作为标头,但我只有部分帧。我可以请求返回StreamSocket::availabel。
如何从websocket读取大数据?
WebSockets在帧中操作,您将始终收到一个帧或什么都不收到。话虽如此,不要麻烦计算可用数据的数量(您可能正在使用以太网1500字节MTU),而是提供存储以容纳您期望接收的最大帧,并调用receiveFrame()。如果消息分散在多个帧之间,则必须在应用程序级别进行处理。参见文档:
从套接字接收帧并将其存储缓冲区中。最多可接收长度字节。如果帧的有效负载更大,WebSocketException引发,并且WebSocket连接必须终止。
即将发布的1.7版本将具有receiveFrame(),它会自动调整缓冲区的大小以适应帧。
要理解分段消息,请参阅RFC 6455中的接收数据。虽然WebSockets被认为是消息传递协议,但在这里可以找到一些关于它们是真正的消息传递还是流媒体的思考。
此外,您发布的代码不会编译,而且在未知大小的缓冲区中写入未知字节数的想法似乎很危险,委婉地说。