accept函数详解

1. 基本概念

accept 函数是一个系统调用,用于在服务器端接受客户端的连接。它会将客户端的信息填入一个指定的套接字结构体中,并返回一个新的套接字描述符,用于与客户端通信。但请注意,accept 函数只能在套接字类型为 SOCK_STREAM(流套接字)的网络套接字上使用,也就是说,它只适用于 TCP 协议。

2. 函数原型

```

#include

#include

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

```

3. 函数参数

* sockfd:服务器端绑定的套接字描述符。

* addr:指向一个用于存放客户端信息的 sockaddr 结构体。

* addrlen:addr 结构体的长度。

4. 函数返回值

* 如果成功,返回一个新的套接字描述符,该描述符可以用于与客户端通信。

* 如果出错,返回 -1,并设置 errno 变量来指示错误原因。

5. 函数使用方法

最基本的使用方法如下:

```

// 创建服务器端套接字

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

// 绑定服务器端套接字

struct sockaddr_in servaddr;

memset(&servaddr, 0, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(PORT);

bind(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr));

// 监听服务器端套接字

listen(sockfd, 10);

// 接受客户端连接

struct sockaddr_in cliaddr;

socklen_t cliaddrlen = sizeof(cliaddr);

int connfd;

connfd = accept(sockfd, (struct sockaddr*)&cliaddr, &cliaddrlen);

// 与客户端通信

char buffer[MAXLINE];

recv(connfd, buffer, MAXLINE, 0);

send(connfd, buffer, strlen(buffer), 0);

// 关闭连接和套接字

close(connfd);

close(sockfd);

```

首先创建了服务器端套接字 sockfd,并将其绑定到指定的 IP 地址和端口号上。然后调用 listen 函数,将 sockfd 设置为监听状态,等待客户端连接请求。

当客户端连接请求到达服务器端时,accept 函数会接受该连接,并返回一个新的套接字描述符 connfd。通过 connfd,我们就可以与客户端建立通信,并完成一系列数据传输的操作。最后,我们需要关闭连接和套接字,释放资源。

6. 函数案例说明

以下是一个简单的服务器端程序,它可以处理多个客户端的连接请求。当客户端连接成功后,服务器端会自动发送一条欢迎消息,并等待客户端发送数据。当客户端发送 exit 消息时,服务器端会关闭该客户端连接,并等待下一个客户端的连接请求。

```

#include

#include

#include

#include

#include

#include ain(int argc, char *argv[])

{

// 创建服务器端套接字

int listenfd = socket(AF_INET, SOCK_STREAM, 0);

if (listenfd == -1)

{

perror("socket");

exit(1);

}

// 绑定服务器端套接字

struct sockaddr_in servaddr;

memset(&servaddr, 0, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

servaddr.sin_port = htons(PORT);

if (bind(listenfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)

{

perror("bind");

exit(1);

}

// 监听服务器端套接字

if (listen(listenfd, 10) == -1)

{

perror("listen");

exit(1);

}

// 处理客户端连接请求

while (1)

{

struct sockaddr_in cliaddr;

socklen_t cliaddrlen = sizeof(cliaddr);

// 接受客户端连接

int connfd = accept(listenfd, (struct sockaddr*)&cliaddr, &cliaddrlen);

if (connfd == -1)

{

perror("accept");

exit(1);

}

// 打印客户端连接信息

char cliip[INET_ADDRSTRLEN];

printf("client IP: %s, port: %d\n",

inet_ntop(AF_INET, &cliaddr.sin_addr, cliip, INET_ADDRSTRLEN),

ntohs(cliaddr.sin_port));

// 发送欢迎消息

char buffer[MAXLINE] = "Welcome to my server!\n";

int n = send(connfd, buffer, strlen(buffer), 0);

if (n == -1)

{

perror("send");

exit(1);

}

// 处理客户端数据

while (1)

{

memset(buffer, 0, MAXLINE);

n = recv(connfd, buffer, MAXLINE, 0);

if (n == -1)

{

perror("recv");

exit(1);

}

else if (n == 0)

{

printf("client closed.\n");

break;

}

else

{

printf("recv: %s\n", buffer);

if (strcmp(buffer, "exit\n") == 0)

{

break;

}

}

}

// 关闭连接和套接字

close(connfd);

}

// 关闭服务器端套接字

close(listenfd);

return 0;

}

```

我们可以打开多个终端,分别在不同的窗口中运行客户端程序,模拟多个客户端的连接。这里我们只给出一个简单的客户端程序,注意指定的 IP 地址和端口号要和服务器端一致。

```

#include

#include

#include

#include

#include

#include ain(int argc, char *argv[])

{

// 创建客户端套接字

int sockfd = socket(AF_INET, SOCK_STREAM, 0);

if (sockfd == -1)

{

perror("socket");

exit(1);

}

// 连接服务器端套接字

struct sockaddr_in servaddr;

memset(&servaddr, 0, sizeof(servaddr));

servaddr.sin_family = AF_INET;

servaddr.sin_addr.s_addr = inet_addr(SERVER_IP);

servaddr.sin_port = htons(PORT);

if (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1)

{

perror("connect");

exit(1);

}

// 与服务器通信

char buffer[MAXLINE];

int n = recv(sockfd, buffer, MAXLINE, 0);

if (n == -1)

{

perror("recv");

exit(1);

}

else

{

printf("%s", buffer);

}

while (1)

{

memset(buffer, 0, MAXLINE);

fgets(buffer, MAXLINE, stdin);

n = send(sockfd, buffer, strlen(buffer), 0);

if (n == -1)

{

perror("send");

exit(1);

}

else if (strcmp(buffer, "exit\n") == 0)

{

break;

}

}

// 关闭客户端套接字

close(sockfd);

return 0;

}

```

总的来说,accept 函数是网络编程中非常重要的一部分,它实现了服务器端对客户端的接受和处理,是实现网络通信的关键。

壹涵网络我们是一家专注于网站建设、企业营销、网站关键词排名、AI内容生成、新媒体营销和短视频营销等业务的公司。我们拥有一支优秀的团队,专门致力于为客户提供优质的服务。

我们致力于为客户提供一站式的互联网营销服务,帮助客户在激烈的市场竞争中获得更大的优势和发展机会!

点赞(120) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿
发表
评论
返回
顶部