上一篇說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。
歡迎多討論,歡迎多發現問題。