上一篇说recv()问题,我描述错误了,很多网友一眼就发现了,而且指了出来,十分感谢。
更难得的是第4位回复者,不但发现我的错误,而且能推测出我实现中是怎么做的,这种分析能力,一方面体现出你一定的实际开发经验,另一方面也体现了你对需求理解能力一定很不错。
正如第4位回复者所说,为了能方便使用经典的同步-阻塞模式,一般会采用select()-recv()搭配调用,还会对recv()进行封装.
ssize_t recv(int s, void *buf, size_t len, int flags);
其行为是有数据就返回,返回实际收到长度: [1, len], 或者正常关闭返回0, 或者出现错误返回-1.
因为我们应用常常喜欢使用包头固定长度 + 包体变长模式来处理,我们是知道我们一定要多长才能正确得到一个协议包的,所以收满一个固定包头长度才能处理,得到包体长度值,再用这个长度去接收包体。
因此做一个封装是常见现象:
bool Read(int sock, char * buffer, size_t len)
{
int ret = 0;
while( len > 0 ) {
ret = recv( sock, buffer, len, 0 );
if( 0 >= ret ) {
return false;
}
buffer += ret;
len -= ret;
}
return true;
}
这个其实也不完全是现实中的,现实中可能返回int, 可能里面有日志处理,可能直接有close()。
总之,这么封装之后,你调用Read( buf, 31), 如果服务器只返回4个字节,既不关闭也不异常,那结果就是一直等待数据到来。
If no messages are available at the socket, the receive calls wait for a message to arrive, unless the socket is non-blocking。
欢迎多讨论,欢迎多发现问题。