客戶端發送 30KB+ 數據,服務端循環 read() 仍無法一次性讀取完整數據,甚至提前返回 EAGAIN。
TCP 是流式協議,無消息邊界。網絡擁塞、滑動窗口、MTU 限制等因素導致數據分片到達,read() 返回已到達的數據,不保證一次讀完應用層預期長度。
send(),檢查返回值累加至總長度。// 先讀 4 字節包頭
int totalLen = readN(sockfd, header, 4);
// 再循環讀取剩餘數據
char *buf = malloc(totalLen);
int received = 0;
while (received < totalLen) {
int n = read(sockfd, buf + received, totalLen - received);
if (n < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) continue; // 非阻塞等待
break; // 錯誤
}
received += n;
}
無論阻塞/非阻塞模式,應用層必須自行實現「收齊指定長度」的邏輯,不可依賴單次 read() 返回預期大小。