2015-12-10 34 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