簡體   English   中英

boost asio檢測/避免接收緩沖區溢出

[英]boost asio detecting / avoiding reception buffer overflow

考慮一個客戶端使用帶有Boost :: asio的TCP在“同步模式”(也稱為“阻止”功能)中向服務器發送數據。

客戶端代碼(跳過有關查詢和io_service的部分):

tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::socket socket( io_service );
boost::asio::connect( socket, endpoint_iterator );
std::array<char, 1000> buf = { /* some data */ };
size_t n = socket.send( boost::asio::buffer(buf) );

這會將整個緩沖區(1000字節)發送到連接的計算機。

現在服務器代碼:

tcp::acceptor acceptor( io_service, tcp::endpoint( tcp::v4(), port ) );
tcp::socket socket( io_service );
boost::system::error_code err;
std::array<char, 500> buff;
size_t n = socket.read_some( boost::asio::buffer(buff), err );
std::cout << "err=" << err.message() << '\n';
  • 它的作用:客戶端通過連接發送1000字節,服務器嘗試將其存儲在500字節的緩沖區中。
  • 我所期望的:服務器錯誤狀態,指出緩沖區太小和/或接收到太多數據。
  • 我得到的是:一個“成功”錯誤值,服務器中的n = 1000。

我在這里想念什么? ASIO無法檢測到緩沖區溢出嗎? 我是否應該繼續使用其他一些類/函數(可能是流?)

裁判(我使用的是1.54):

您嚴重誤解了TCP。

TCP是字節流。 TCP流中沒有數據包邊界。 在關閉套接字之前,所有字節均形成單個流。 (與UDP不同)

Boost.Asio知道這一點。 只要流是開放的,就無法說出流最終有多大。 如果您有一個500字節的緩沖區,Boost Asio可以用(可能無界的)TCP流的前500個字節填充它。

但是, read_some只是查看已經可用的內容。 在您的情況下,只有1000字節,完全可以預期網卡上的全部1000字節都可用。 這部分沒有錯誤。 它不適合您的緩沖區,但這在網絡端不是問題。

TCP和UDP都沒有辦法傳達回信息,表明接收器正在等待一個較小的數據包。 那是應用程序級的邏輯,您可以在應用程序級進行處理。 例如,HTTP具有413 Payload Too Large 因此,Boost.Asio不提供標准機制。

您確實收到了500個字節,並且可以通過再次調用asio讀取最后500個字節。 在我看來,您只是誤解了asio的行為。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM