当我呼叫async_write()
时,在我再次呼叫async_write()
之前,远程对等方没有收到数据。例如,我有3个数据包,a
,b
和c
:
SendPacket(a); // the remote side receives nothing
SendPacket(b); // the remote side receives packet a
SendPacket(c); // the remote side receives packet b
这是我的发送代码:
void Session::SendPacket(packet p)
{
dword len = p.Lenght();
byte* buffer_send = new byte[len + 4]; //4 cause of the header
memcpy(buffer_send + 4, p.GetRaw(), len); // copy everything to the buffer +4, 0-4 is header
m_codec.EncodePacket(buffer_send, len);
boost::asio::async_write(m_socket, boost::asio::buffer(buffer_send, len + 4),
boost::bind(&Session::OnPacketSend, this, len + 4, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred, buffer_send));
}
void Session::OnPacketSend(int len, const boost::system::error_code &e, size_t bytes_transferred, byte* buf)
{
// this asynchronously fires when packet data is sent
delete[] buf;
if (e || bytes_transferred != len)
{
Stop();
return;
}
}
我这样使用它:
packet pp;
pp.WriteWord(0);
pp.WriteDword(4);
pp.WriteWord(0);
SendPacket(pp);
此外,当SendPacket()
按值而不是引用接受packet
时,会发生崩溃。
的Gr
答案 0 :(得分:2)
当少量数据被写入套接字时,例如原始代码(12字节〜),人们通常会观察到由于{{3而将后续数据写入套接字之前未发送数据的行为}}。简而言之,许多系统将尝试通过将小的出站消息连接成随后发送的单个消息来缓解IP / TCP拥塞。要在每个套接字的基础上显式禁用此行为,请设置Nagle's algorithm选项:
boost::asio::ip::tcp::socket socket(io_service);
// ...
boost::asio::ip::tcp::no_delay option(true);
socket.set_option(option);
如果有足够的带宽,禁用Nagle可能会导致更高的吞吐量。然而,仍然可能值得检查应用程序协议和逻辑,以确定何时或什么数据可以缓冲,以及何时需要立即发送。