socket select 等待 accept
时间: 2023-06-19 17:04:30 浏览: 98
当使用 `socket` 创建一个服务器端套接字后,需要使用 `bind` 函数将该套接字与一个本地地址绑定。然后,使用 `listen` 函数将该套接字转换为一个监听套接字,等待客户端的连接请求。在等待客户端请求连接时,可以使用 `select` 函数来监视该套接字是否有连接请求到来。
在使用 `select` 函数时,需要将监听套接字添加到一个文件描述符集合中,并设置超时时间。当有连接请求到来时,`select` 函数会返回该套接字的文件描述符,然后可以使用 `accept` 函数来接受该连接请求,返回一个新的套接字,用于与客户端进行通信。接下来,可以将该新的套接字加入到一个新的文件描述符集合中,再次使用 `select` 函数来等待客户端的数据发送。
相关问题
socket select 等待 accept 代码
下面是一个使用 select 等待 accept 的示例代码:
```python
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind(('localhost', 8000))
server_socket.listen(5)
sockets_list = [server_socket]
while True:
read_sockets, _, _ = select.select(sockets_list, [], [])
for sock in read_sockets:
if sock == server_socket:
client_socket, client_address = server_socket.accept()
sockets_list.append(client_socket)
print('Accepted new connection from {}:{}'.format(*client_address))
else:
data = sock.recv(1024)
if data:
print(data.decode())
else:
sock.close()
sockets_list.remove(sock)
print('Connection closed')
```
在上面的代码中,我们首先创建了一个服务器套接字 `server_socket`,并将其绑定到本地主机的端口 8000 上。然后,我们使用 `select` 函数来等待新的连接。在每次循环中,我们调用 `select` 函数并传入一个包含 `server_socket` 的套接字列表 `sockets_list`,以及空的读取、写入和错误列表。`select` 函数将阻塞,直到有一个套接字处于可读状态,然后返回可读套接字的列表 `read_sockets`。
我们遍历 `read_sockets` 列表,如果其中的套接字是 `server_socket`,则表示有新的客户端连接请求。我们调用 `accept` 方法来接受连接请求,并将新的客户端套接字 `client_socket` 添加到 `sockets_list` 列表中。我们还打印出客户端的地址和端口号。
如果读取的套接字不是 `server_socket`,则表示有数据到达。我们使用 `recv` 方法来接收数据,并将其打印到控制台上。
最后,如果 `recv` 方法返回空数据,则表示客户端已关闭连接。我们关闭套接字并从 `sockets_list` 列表中删除该套接字。
linux c socket select 等待 accept 代码
以下是一个使用 `select` 函数等待 `accept` 的示例代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/select.h>
#define LISTEN_BACKLOG 50
#define MAX_EVENTS 10
int main(int argc, char *argv[]) {
int listen_fd, conn_fd;
struct sockaddr_in server_addr, client_addr;
socklen_t client_addr_len;
fd_set read_fds, write_fds, except_fds;
int max_fd, ret;
// 创建监听套接字
listen_fd = socket(AF_INET, SOCK_STREAM, 0);
if (listen_fd < 0) {
perror("socket error");
exit(EXIT_FAILURE);
}
// 设置地址复用选项
int optval = 1;
if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)) < 0) {
perror("setsockopt error");
exit(EXIT_FAILURE);
}
// 绑定地址
memset(&server_addr, 0, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(8888);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
perror("bind error");
exit(EXIT_FAILURE);
}
// 监听
if (listen(listen_fd, LISTEN_BACKLOG) < 0) {
perror("listen error");
exit(EXIT_FAILURE);
}
// 初始化 fd_set
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&except_fds);
FD_SET(listen_fd, &read_fds);
max_fd = listen_fd;
while (1) {
// 使用 select 等待读事件
ret = select(max_fd + 1, &read_fds, &write_fds, &except_fds, NULL);
if (ret < 0) {
perror("select error");
exit(EXIT_FAILURE);
}
// 处理读事件
if (FD_ISSET(listen_fd, &read_fds)) {
client_addr_len = sizeof(client_addr);
conn_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &client_addr_len);
if (conn_fd < 0) {
perror("accept error");
continue;
}
// 将新连接的套接字加入 fd_set
FD_SET(conn_fd, &read_fds);
if (conn_fd > max_fd) {
max_fd = conn_fd;
}
printf("new connection from %s:%d\n", inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
}
// 处理其它读事件
for (int fd = listen_fd + 1; fd <= max_fd; fd++) {
if (FD_ISSET(fd, &read_fds)) {
// TODO: 处理读事件
}
}
// 清空 fd_set
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_ZERO(&except_fds);
FD_SET(listen_fd, &read_fds);
for (int fd = listen_fd + 1; fd <= max_fd; fd++) {
if (FD_ISSET(fd, &read_fds) || FD_ISSET(fd, &write_fds) || FD_ISSET(fd, &except_fds)) {
FD_SET(fd, &read_fds);
}
}
}
exit(EXIT_SUCCESS);
}
```
代码中使用 `select` 函数等待监听套接字的读事件,一旦监听套接字上有新的连接请求,就调用 `accept` 函数接受连接,并将新连接的套接字加入 `fd_set` 中,并更新 `max_fd`。然后在 `for` 循环中遍历其它套接字,处理读事件。最后清空 `fd_set`,重新添加需要监听的套接字。
阅读全文
相关推荐
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![application/x-rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![gz](https://img-home.csdnimg.cn/images/20210720083447.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![txt](https://img-home.csdnimg.cn/images/20241231045021.png)
![doc](https://img-home.csdnimg.cn/images/20241231044833.png)
![-](https://img-home.csdnimg.cn/images/20241231045021.png)
![-](https://img-home.csdnimg.cn/images/20241231045021.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)
![](https://csdnimg.cn/download_wenku/file_type_ask_c1.png)