首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

Beej 網絡編程指南第 13 篇:accept() 接受連線詳解

     編輯:關於C

accept() 函數原型

#include <sys/types.h>
#include <sys/socket.h>

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);

參數說明

  • sockfd:監聽套接字描述符(由 socket() 建立並經 bind()、listen() 後)。
  • addr:指向 sockaddr_storage 的指標,用於接收客戶端位址資訊(IP + 埠)。
  • addrlen:輸入輸出參數,輸入時為 addr 緩衝區大小,返回時為實際寫入的位址結構大小。

返回值

  • 成功:返回新的已連線套接字描述符(new_fd),專供 send()/recv() 通訊。
  • 失敗:返回 -1,設定 errno。

原監聽套接字 sockfd 繼續保持監聽狀態,可再次呼叫 accept() 接受新連線。

完整伺服器範例

#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#define MYPORT "3490"
#define BACKLOG 10

int main(void) {
    struct sockaddr_storage their_addr;
    socklen_t addr_size;
    struct addrinfo hints, *res;
    int sockfd, new_fd;

    memset(&hints, 0, sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_flags = AI_PASSIVE;

    getaddrinfo(NULL, MYPORT, &hints, &res);
    sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
    bind(sockfd, res->ai_addr, res->ai_addrlen);
    listen(sockfd, BACKLOG);

    addr_size = sizeof(their_addr);
    new_fd = accept(sockfd, (struct sockaddr*)&their_addr, &addr_size);
    // 此後使用 new_fd 進行 send/recv 通訊
    // 若只接受單一連線,可 close(sockfd) 關閉監聽
    return 0;
}

關鍵點

  1. accept() 會阻塞直到有連線到達(除非套接字設為非阻塞)。
  2. 新套接字 new_fd 繼承監聽套接字的屬性(協議族、型別、協議)。
  3. 客戶端位址資訊可用 getnameinfo() 轉為可讀字串。
  4. 錯誤處理:生產代碼必須檢查每個系統調用的返回值。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved