乐闻世界logo
搜索文章和话题

套接字编程-listen()和accept()之间有什么区别?

5 个月前提问
4 个月前修改
浏览次数54

1个答案

1

在套接字编程中,listen()accept()函数扮演着非常关键的角色,特别是在TCP服务器的建立和管理客户端连接请求中。下面我会分别解释这两个函数的功能和它们之间的区别。

listen() 函数

listen()函数主要用于TCP服务器端。在服务器端已经通过socket()创建了一个套接字并通过bind()绑定了一个本地地址后,listen()函数就被用来启用该套接字接受来自客户端的连接请求。

  • 参数: listen()函数通常接受两个参数:套接字描述符和backlog。backlog参数定义了请求队列中最多可以有多少个客户端连接等待接受。
  • 功能: 当调用listen()后,之前的套接字从一个主动套接字变为了一个被动套接字,这意味着它可以接受来自客户端的连接请求,但自己不会主动发起连接。

accept() 函数

在服务器调用listen()后,accept()函数被用来从已经建立的队列中接受一个客户端的连接请求。

  • 参数: accept()函数通常接受三个参数:监听的套接字描述符、指向struct sockaddr的指针用于获取客户端的地址信息,以及地址结构的大小。
  • 功能: accept()的工作是阻塞当前进程,直到一个客户端连接请求到达。一旦客户端连接建立,accept()会返回一个新的套接字描述符,这个新的描述符用于与新连接的客户端进行通信。原来的套接字继续在listen()状态下,接受其他的连接请求。

区别

总结来说,listen()accept()的主要区别如下:

  • 作用对象: listen()作用于一个未连接的套接字并使其能够接受连接请求,而accept()是从监听队列中实际接受一个连接请求。
  • 返回值: listen()不返回连接相关的信息;accept()通过返回一个全新的套接字描述符,用于后续的数据交换。
  • 功能: listen()仅仅是准备套接字接受连接请求,不参与实际的数据传输;accept()则是开始了一个新的会话,用于具体的数据传输。

示例

假设我们正在创建一个简单的TCP服务器,我们先创建和绑定套接字,然后调用listen()让套接字进入被动监听状态。当一个客户端尝试连接时,我们通过accept()接受这个连接请求,并通过返回的新套接字与客户端进行通信。

c
int sockfd, new_sockfd; // 套接字描述符 struct sockaddr_in host_addr, client_addr; // 地址结构 socklen_t sin_size; int yes = 1; sockfd = socket(PF_INET, SOCK_STREAM, 0); // 创建套接字 host_addr.sin_family = AF_INET; // 主机字节序 host_addr.sin_port = htons(12345); // 网络字节序的端口号 host_addr.sin_addr.s_addr = INADDR_ANY; // 自动填充IP memset(&(host_addr.sin_zero), '\0', 8); // 清零结构体剩余部分 bind(sockfd, (struct sockaddr *)&host_addr, sizeof(struct sockaddr)); // 绑定地址 listen(sockfd, 5); // 开始监听,队列长度为5 sin_size = sizeof(struct sockaddr_in); new_sockfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size); // 接受连接请求

通过这个示例,我们可以看到listen()accept()在建立TCP服务器中的作用和区别。

2024年6月29日 12:07 回复

你的答案