2015-12-10 33 views
1

我使用Net :: SocketReactor关于proccess连接。当数据输入插座称为如下代码:Poco Websocket无法读取大数据

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读取大量数据?

回答

2

WebSockets以帧的形式运行,并且您将始终收到一帧或没有任何内容。有了这个说法,不要费心计算出可用数据的数量(您可能会触及以太网1500字节MTU),但会提供存储空间以容纳您期望收到的最大帧,并致电receiveFrame()。如果消息在多个帧之间分割,则必须在应用程序级别处理这些消息。见documentation

从插座并将其存储在缓冲器 接收帧。最多可接收长度字节。如果 帧的有效负载较大,则抛出WebSocketException ,并且WebSocket连接必须以 终止。

即将发布的1.7版本将有receiveFrame()自动调整缓冲区以适应帧。

要了解分段消息,请参阅中的Receiving Data。虽然WebSocket被设想为消息传递协议,但是他们是否真的在消息传递或流媒体上发表的意见可以在here找到。

此外,您发布的代码无法编译,并且在未知大小的缓冲区中写入未知数量的字节的想法看起来很危险,要稍微说明一下。

+0

你是对的!作为参数的指针是个坏主意。我试图简化代码。 –

+0

我是否正确理解我们应该忽略结果StreamSocket :: availabel(),并使用int WebSocket :: receiveFrame(Poco :: Buffer &buffer,int&flags)? –

+0

是的,你理解它是正确的。但是,带有'Poco :: Buffer'的版本尚未发布;所以,除非你使用github开发代码,你应该使用[固定缓冲区]的版本(https://github.com/pocoproject/poco/blob/poco-1.6.1/Net/src/WebSocket.cpp#L109 ),并确保为预期的框架提供足够的空间。 – Alex