成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

騰訊后端 C++一面:recv 返回值,什么錯誤是可接受的?

開發
在 C/C++網絡編程中,尤其是在處理 TCP 套接字時,recv函數扮演著基石般的角色。它是從連接對端讀取傳入數據的主要機制。

在 C/C++網絡編程中,尤其是在處理 TCP 套接字時,recv函數扮演著基石般的角色。它是從連接對端讀取傳入數據的主要機制。

1. recv 函數原型

我們先從標準的 POSIX 函數原型開始:

#include <sys/socket.h>

ssize_t recv(int sockfd, void *buf, size_t len, int flags);
  • sockfd: 接收數據的套接字文件描述符。
  • buf: 指向用于存儲接收數據的緩沖區的指針。
  • len: buf緩沖區的最大長度,即本次調用最多接收的字節數。
  • flags: 控制接收操作的標志位(例如 MSG_PEEK, MSG_WAITALL)。通常設為 0 表示標準行為。

返回值 ssize_t 類型對于理解調用的結果至關重要。

2. 解讀 recv 返回值

recv 函數的返回值主要有以下三種情況:

(1) 返回值 > 0: 成功接收數據

  • 含義: 調用成功,并從對端接收到了數據。 
  • 值: 返回值表示實際接收到并放入buf中的字節數。 
  • 注意: 這個值可能小于你請求的 len,即使發送方發送了更多的數據。這是正常現象,原因包括網絡緩沖區大小、TCP 分段、以及調用時套接字接收緩沖區中實際可用的數據量等。
  • 處理: 處理接收到的 返回值 這么多字節的數據。如果你的應用層協議期望更多的數據,你可能需要在一個循環中再次調用 recv,直到接收到完整的消息或發生錯誤/連接關閉。

(2) 返回值 == 0: 對端已正常關閉連接

  • 含義: 遠端對等方(peer)已經執行了有序關閉序列(發送了 FIN 包),表示它不會再發送任何數據了。
  • 值: 0。 
  • 注意: 這不是一個錯誤。這是一個信號,表明連接的讀取方向已經由對端關閉。你無法再從此連接接收到任何數據。
  • 處理: 識別到連接正在關閉。通常應停止嘗試接收數據,可能需要關閉你自己的寫端(如果還沒關閉,使用 shutdown(sockfd, SHUT_WR)),并最終調用 close(sockfd) 來釋放套接字資源。

(33) 返回值 == -1: 發生錯誤

  • 含義: recv 調用失敗。 
  • 值: -1。
  • 處理: 這是錯誤處理的關鍵所在,不同的值處理方式是不一樣的。

錯誤處理:哪些 errno 值是“可接受”的?

當 recv 返回 -1 時,并非所有的 errno 值都意味著連接已死或必須立即放棄。有些錯誤指示的是臨時狀態或需要特定處理邏輯的情況,而不是直接終止連接。這些就是在面試題里面說的“可接受”的錯誤。

(1) “可接受” / 非致命錯誤

① EAGAIN 或 EWOULDBLOCK: (這兩個宏通常具有相同的值)

  • 場景: 主要發生在套接字被設置為非阻塞模式 (O_NONBLOCK) 時。
  • 含義: 當前套接字的接收緩沖區中沒有數據可讀,并且在不阻塞的情況下無法立即完成讀取操作。這不是一個真正的錯誤,而是對套接字狀態的一種描述。
  • 處理: 不要關閉連接。這是非阻塞 I/O 中的預期行為。標準的處理方式是使用 I/O 多路復用機制(如 epoll, select, poll)。這些機制會通知你套接字何時變為可讀狀態,屆時你再安全地重試 recv 調用。在一個緊密循環中反復調用 recv 而不等待(忙等待)是非常低效的。
// 概念性的非阻塞循環(結合epoll/select)
while (true) {
    // 使用epoll_wait, select等等待sockfd變為可讀
    // ... 等待邏輯 ...

    ssize_tbytes_received= recv(sockfd, buffer, sizeof(buffer), 0);

    if (bytes_received > 0) {
        // 處理數據...
    } elseif (bytes_received == 0) {
        // 對端關閉連接
        handle_close(sockfd);
        break;
    } else { // bytes_received == -1
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            // 當前無數據可用,返回繼續等待(epoll/select)
            continue;
        } elseif (errno == EINTR) {
            // 被信號中斷,直接重試
            continue;
        } else {
            // 發生其他錯誤
            perror("recv failed"); // 打印錯誤信息
            handle_error_close(sockfd); // 處理錯誤并關閉連接
            break;
        }
    }
}

② EINTR:

  • 含義:recv系統調用被一個應用程序捕獲到的信號(signal)所中斷,并且中斷發生在任何數據傳輸完成之前。
  • 處理:這通常被認為是一個暫時的中斷。操作并未完成,但這并不一定意味著套接字本身有問題。標準的做法是簡單地在循環中立即重試 recv調用。

(2) 致命 / 不可恢復錯誤

這些錯誤通常表明連接本身、套接字狀態或程序邏輯存在問題。在這些錯誤發生后繼續在該套接字上操作通常是無意義或不可能的。

  • ECONNRESET: 連接被對端重置。對方發送了 RST(重置)包,很可能是因為對方異常終止或網絡問題。連接已失效。
  • ENOTCONN: 套接字未連接(例如,在 TCP 套接字上調用 connect 或 accept 之前,或連接已斷開后嘗試 recv)。
  • ETIMEDOUT: 連接超時。可能在連接建立階段發生,或在數據傳輸過程中由于網絡狀況極差或設置了 SO_RCVTIMEO 并發生較長超時而發生。通常意味著連接不可用。
  • ECONNREFUSED: 遠程主機主動拒絕連接(更常見于 connect 調用,但在特定的 UDP recvfrom 場景下也可能遇到)。
  • EBADF: 無效的文件描述符 (sockfd 沒有指向一個打開的套接字)。這是程序邏輯錯誤。
  • EFAULT: 傳入的緩沖區指針 buf 指向了進程地址空間之外的無效內存。這是程序邏輯錯誤。
  • EINVAL: 提供了無效的參數(例如,無效的 flags)。程序邏輯錯誤。
  • ENOTSOCK: 文件描述符 sockfd 指的不是一個套接字。程序邏輯錯誤。

對于致命錯誤的處理: 記錄具體的 errno 值和錯誤信息(使用 perror 或 strerror),清理與該連接相關的資源,并調用 close(sockfd) 關閉套接字。

回答

  • 區分出 recv 的三種返回值 (>0, 0, -1) 及其含義。
  • 知道 -1 需要檢查 errno。
  • 明確指出 EAGAIN/EWOULDBLOCK 和 EINTR 是可接受的、需要特殊處理(等待/重試)的錯誤,尤其是在非阻塞 I/O 場景下 EAGAIN/EWOULDBLOCK 是正常情況。

對于“什么錯誤是可接受的?”這個問題,最核心的答案是 EAGAIN (或 EWOULDBLOCK) 和 EINTR。

責任編輯:趙寧寧 來源: CppPlayer
相關推薦

2025-06-16 03:22:00

2024-01-24 11:35:28

C++多返回值開發

2024-06-06 09:03:37

MySQL數據庫共享鎖

2025-05-27 10:15:00

void*函數開發

2021-08-13 11:31:23

HTTP

2021-08-04 12:11:40

GitHub開發社區FSF

2024-09-27 16:33:44

2022-07-26 07:51:40

ThreadRunnableFuture

2025-04-15 10:00:00

Feign負載均衡微服務

2024-10-22 15:25:20

2022-05-11 22:15:51

云計算云平臺

2025-03-20 09:59:55

Spring@ProfileJava

2009-07-30 14:38:36

云計算

2020-09-19 17:46:20

React Hooks開發函數

2022-04-12 11:38:06

C語言全局變量

2025-03-24 07:35:00

開發注解Spring

2024-11-26 08:52:34

SQL優化Kafka

2009-09-07 03:07:11

C# Main方法

2022-01-17 06:58:35

C語言函數錯誤碼

2011-12-22 20:53:40

Android
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 在线免费观看成年人视频 | www.一区二区三区.com | 久久久观看 | 免费播放一级片 | av中文字幕在线播放 | 97超碰在线免费 | 国产特级毛片aaaaaa喷潮 | 狠狠操狠狠 | 国产麻豆乱码精品一区二区三区 | 欧美一区二区三区 | h免费观看 | 日韩精品一区二区三区视频播放 | 久久成人国产 | 国产一区久久 | 操视频网站 | 久久国产精品久久国产精品 | 精品国产一区二区在线 | 日韩精品视频在线免费观看 | av一区在线观看 | 在线播放中文字幕 | 精品一二三区在线观看 | 成人av免费网站 | 欧美日韩高清 | 精品久久久久久18免费网站 | 欧美黄a | 亚洲精品99999 | 天天拍夜夜爽 | 久久久国产一区二区三区 | 五月天天丁香婷婷在线中 | 成人国产在线观看 | 久久在看 | 免费在线精品视频 | 中文字幕在线电影观看 | 午夜精品久久久久久久久久久久 | 亚洲国产精品久久久久秋霞不卡 | 美女视频黄色片 | 美女黄网| 视频在线观看一区二区 | 人成久久 | 免费久草 | 亚洲 欧美 精品 |