接受從 listening socket 進來的連線 函式原型(Prototype) #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 的溝通。 原本用來 listen 的 socket 仍然還是會留著,當有新連線進來時,一樣是用 accept() call 來接受新的連線。
accept() 通常會 block(阻塞),而你可以使用 select() 事先取得 listen 中的 socket descriptor 狀態,檢查 socket 是否就緒可讀(ready to read)。若為就緒可讀,則表示有新的連線正在等待被 accept()!另一個方式是將 listen 中的 socket 使用 fcntl() 設定 O_NONBLOCK 旗標,然後 listen 中的 socket descriptor 就不會造成 block,而是傳回 -1,並將 errno 設定為 EWOULDBLOCK。 由 accept() 傳回的 socket descriptor 是如假包換的 socket descriptor,開啟並與遠端主機連線,如果你要結束與 client 的連線,必須用 close() 關閉。 傳回值 accept() 傳回新連線的 socket descriptor,錯誤時傳回 -1,並將 errno 設定適當的值。 範例 struct sockaddr_storage their_addr; socklen_t addr_size; struct addrinfo hints, *res; int sockfd, new_fd; // 首先:使用 getaddrinfo() 填好位址結構: memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; // 使用 IPv4 或 IPv6,都可以 hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE; // 幫我填好我的 IP getaddrinfo(NULL, MYPORT, &hints, &res); // 建立一個 socket、bind 它,並對它進行 listen: 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); // 準備與 socket descriptor new_fd 溝通!參考 socket(), getaddrinfo(), listen(), struct sockaddr_in |
09-Man 使用手冊 >