// 分支 1:單次 recv
if (select(...) > 0) {
nlen = recv(sockfd, buf, 199, 0); // 返回實際讀取位元組數
}
// 分支 2:while 迴圈
while ((nlen = recv(sockfd, buf, 199, 0)) > 0) {
// nlen 總是 1?
}
select 就緒後,recv 讀取緩衝區所有可用資料(最多 199 位元組),返回實際長度(如 199)。while 迴圈**每次只讀 1 位元組**?否。實際上 recv 仍會讀取所有可用資料。但觀察到 nlen=1 可能原因:
send 只發 1 位元組(Nagle 演算法或應用層邏輯)。SO_RCVBUF=1)。buf 指標未重設,pcBuffer += nlen 導致後續 recv 寫入越界記憶體,行為未定義。
int total = 0, expected = 199;
while (total < expected) {
int n = recv(sockfd, buf + total, expected - total, 0);
if (n <= 0) { /* 錯誤/關閉 */ break; }
total += n;
}
// 此時 total 為完整訊息長度
fd_set readfd;
FD_ZERO(&readfd);
FD_SET(sockfd, &readfd);
struct timeval tv = {5, 0}; // 5 秒超時
int ret = select(sockfd + 1, &readfd, NULL, NULL, &tv);
if (ret > 0 && FD_ISSET(sockfd, &readfd)) {
// 可讀,執行上述接收迴圈
}
while(recv()) 觀察到返回 1 多半是發送端逐位元組發送或接收緩衝區指標管理錯誤。正確做法:預期長度循環讀取、指標偏移累加、檢查返回值 <=0 處理斷線/錯誤。