TCP套接字如何知道它已读取所有内容?

Lai*_*uan 1 sockets tcp boost-asio

有一个非常简单的socket服务器实现boost::asio.

tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
tcp::socket(io_service) sock;
a.accept(sock);
char data[1024];
boost::system::error_code error;
size_t length = sock->read_some(boost::asio::buffer(data), error);
std::cout << "Got: " << data << std::endl;
Run Code Online (Sandbox Code Playgroud)

它的客户端看起来像:

size_t request_length = strlen(request);
boost::asio::write(s, boost::asio::buffer(request, request_length));
Run Code Online (Sandbox Code Playgroud)

(两者都来自官方的例子)

当我发送hello, world!到套接字时,我Got: hello, world!立即得到了.但它的缓冲区有1024个字节.怎么知道什么时候读完?

编辑:

对不起,我的描述很糟糕.我的问题是如何read_some()知道何时应该返回.

Dav*_*ger 7

read_some()将从接收缓冲区中读取至少一个字节时返回.如果接收缓冲区中有数据,它将尝试读取尽可能多的指定大小.在单次读取期间,它可能会也可能不会读取整个消息.

在你的情况下,你似乎偶然得到了整个信息.read_some()很可能只读取一个字节.最好read_some()从循环内调用缓冲区的起始索引,增加前一次读取的长度.

就像是:

size_t length = 0;
while(length < MESSAGE_LENGTH)
{
    length += sock->read_some(boost::asio::buffer(&data[lenth], 1024 - length), error);
}
Run Code Online (Sandbox Code Playgroud)

这当然是为了说明而简化的.您还应该注意错误条件等.但这应该足以让你开始.