read 一直阻塞,直到數據到達。read 立即返回。errno = EWOULDBLOCK(操作本應阻塞但因非阻塞模式立即返回)。典型讀取模式:
if ((nread = read(sock_fd, buffer, len)) < 0) {
if (errno == EWOULDBLOCK) return 0; // 暫無數據
else return -1; // 真正錯誤
}
return nread;
write 阻塞直到可寫。errno = EWOULDBLOCK。典型寫入循環:
int write_pos = 0, nLeft = nLen;
while (nLeft > 0) {
int nWrite = write(sock_fd, data + write_pos, nLeft);
if (nWrite <= 0) {
if (errno == EWOULDBLOCK) nWrite = 0;
else return -1;
}
nLeft -= nWrite;
write_pos += nWrite;
}
return nLen;
connect 發送 SYN 並等待三次握手完成才返回。connect 發起握手後立即返回,errno = EINPROGRESS。後續需用 select/poll 監聽可寫事件判斷連接結果。accept 在連接隊列為空時阻塞。accept 立即返回,無連接時 errno = EWOULDBLOCK。int flag = fcntl(fd, F_GETFL, 0); flag |= O_NONBLOCK; fcntl(fd, F_SETFL, flag);
int on = 1; ioctl(fd, FIONBIO, &on);
非阻塞 Socket 配合 I/O 多路復用(select/poll/epoll)是高併發服務器的基石,核心在於「不等待,輪詢就緒事件」。