accept
函数是用于在服务器端接受客户端连接的系统调用。以下是 accept
函数的详细解读:
#include <sys/types.h>
#include <sys/socket.h>int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
-
sockfd
:- 是一个已经通过
socket
函数创建并绑定到特定地址的监听套接字(通常是服务器的监听套接字)。
- 是一个已经通过
-
addr
:- 是一个指向
struct sockaddr
类型的指针,用于存储连接的对端地址信息。可以为NULL
,表示不关心对端地址。
- 是一个指向
-
addrlen
:- 是一个指向
socklen_t
类型的指针,用于指定addr
缓冲区的大小。在调用accept
之前,addrlen
应该被初始化为struct sockaddr
缓冲区的大小,函数返回时,addrlen
会被设置为实际地址结构的长度。
- 是一个指向
-
返回值:
- 如果连接成功,返回一个新的文件描述符,这个文件描述符用于与客户端通信。
- 如果失败,返回 -1,并设置
errno
表示错误原因。
示例用法:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>int main() {// 创建套接字int listenfd = socket(AF_INET, SOCK_STREAM, 0);if (listenfd == -1) {perror("socket");exit(EXIT_FAILURE);}// 绑定地址struct sockaddr_in server_addr;memset(&server_addr, 0, sizeof(server_addr));server_addr.sin_family = AF_INET;server_addr.sin_addr.s_addr = INADDR_ANY;server_addr.sin_port = htons(8080);if (bind(listenfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) == -1) {perror("bind");close(listenfd);exit(EXIT_FAILURE);}// 监听连接if (listen(listenfd, 10) == -1) {perror("listen");close(listenfd);exit(EXIT_FAILURE);}// 等待客户端连接struct sockaddr_in client_addr;socklen_t client_len = sizeof(client_addr);int clientfd = accept(listenfd, (struct sockaddr*)&client_addr, &client_len);if (clientfd == -1) {perror("accept");close(listenfd);exit(EXIT_FAILURE);}// 至此,成功建立连接,可以使用 clientfd 与客户端通信// 关闭套接字close(clientfd);close(listenfd);return 0;
}
在这个示例中,accept
函数被用于等待并接受客户端的连接。它会阻塞程序的执行,直到有客户端连接请求到达,然后创建一个新的套接字 clientfd
用于与客户端通信。在实际使用中,你可以在 clientfd
上进行读写操作,与客户端进行数据交换。连接结束后,应该关闭 clientfd
和 listenfd
。