天天看點

accept()的man手冊

  • 英文小冊原文位址:​​beej.us/guide/bgnet…​​
  • 作者:Beej
  • 中文翻譯位址:​​www.chanmufeng.com/posts/netwo…​​

接受偵聽套接字上傳入的連接配接。

函數原型

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

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

說明

一旦你拿到了 SOCK_STREAM 類型的socket, 并将 socket 設定好可以用來監聽( listen()) 進入的連接配接,然後你就能調用 accept() 獲得一個新的 socket descriptor,便于與後續新連接配接 client 的通信。

原本被監聽的socket仍然會被保留,當有新的連接配接進來時,通過調用accept()擷取這個新連接配接。主要的參數如下所示:

  • s:listen()中的socket descriptor。
  • addr:這裡寫入連接配接到你這裡的client的位址。
  • addrlen:這裡會填入addr參數中傳回的資料的大小。假設你得到了一個structsockaddr_in,你可以安全地忽略它,因為這是你為addr傳入的類型。

accept() 通常會阻塞,而你可以使用 select() 事先取得 listen 中的 socket descriptor 狀态,檢查 socket 是否已經可讀(ready to read)。若已經可讀,則表示有新的連接配接正在等待被 accept()!另一個方式是将 listen 中的 socket 使用 fcntl() 設定 O_NONBLOCK 選項,然後 listen 中的 socket descriptor 就不會造成 block,而是傳回 -1,并将 errno 設定為 EWOULDBLOCK。

傳回值

例子

struct sockaddr_storage their_addr;
socklen_t addr_size;
struct addrinfo hints, *res;
int sockfd, new_fd;

// first, load up address structs with getaddrinfo():

memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;  // use IPv4 or IPv6, whichever
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;     // fill in my IP for me

getaddrinfo(NULL, MYPORT, &hints, &res);

// make a socket, bind it, and listen on it:

sockfd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
bind(sockfd, res->ai_addr, res->ai_addrlen);
listen(sockfd, BACKLOG);

// now accept an incoming connection:

addr_size = sizeof their_addr;
new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &addr_size);

// ready to communicate on socket descriptor new_fd!      

參閱