#include <sys/socket.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <stdlib.h> #include <netinet/in.h> #define BACKLOG 5 #define MAXLINE 1024 int clients[BACKLOG]; int main() { int listen_fd = socket(AF_INET, SOCK_STREAM, 0); if (listen_fd == -1) { printf("socket error[%d]:%s\n", errno, strerror(errno)); exit(errno); } struct sockaddr_in server_addr; memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(55555); if (bind(listen_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { printf("bind error[%d]:%s\n", errno, strerror(errno)); exit(errno); } int yes = 1; if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) { printf("setsockopt error[%d]:%s\n", errno, strerror(errno)); exit(errno); } if (listen(listen_fd, BACKLOG) == -1) { printf("listen error[%d]:%s\n", errno, strerror(errno)); exit(errno); } fd_set rset; int maxfd = listen_fd; int conn_count = 0; int i = 0; while(1) { FD_ZERO(&rset); FD_SET(listen_fd, &rset); for (i=0; i< conn_count; i++) { if (clients[i]!=0) { FD_SET(clients[i], &rset); } } struct timeval tv; tv.tv_sec = 30; tv.tv_usec = 0; int ret = select(maxfd+1, &rset, NULL, NULL, &tv); if (ret < 0) { printf("select error[%d]:%s\n", errno, strerror(errno)); break; }else if (ret == 0) { printf("select timeout\n"); continue; } if (FD_ISSET(listen_fd, &rset)) { struct sockaddr_in client_addr; int sin_len = sizeof(client_addr); int client_fd = accept(listen_fd, (struct sockaddr *)&client_addr, &sin_len); if (client_fd == -1) { printf("accept error[%d]:%s\n", errno, strerror(errno)); continue; } if (client_fd > maxfd) maxfd = client_fd; if (conn_count < BACKLOG) { printf("accept new connection %d\n", client_fd); clients[conn_count++] = client_fd; FD_SET(client_fd, &rset); }else { printf("max connections, exit\n"); send(client_fd, "bye\n", 5, 0); close(client_fd); break; } } for(i=0; i<conn_count; i++) { if(FD_ISSET(clients[i], &rset)) { char buffer[MAXLINE]={0}; int recv_len = recv(clients[i], buffer, MAXLINE, 0); if (recv_len < 0) { printf("client %d recv error[%d]:%s\n", clients[i], errno, strerror(errno)); printf("close client"); close(clients[i]); FD_CLR(clients[i], &rset); clients[i]=0; continue; } printf("client %d recv len:%d, msg:%s\n", clients[i], recv_len, buffer); } } } for (i=0; i<BACKLOG; i++) { if (clients[i]!=0) { send(clients[i], "bye\n", 5, 0); printf("close client %d\n", clients[i]); close(clients[i]); } } return 0; }
相关推荐
在Windows环境下进行网络编程,Socket多路复用是一种高效处理多个连接请求的技术,它允许多个套接字(sockets)在同一时刻被监控,以便服务端能够同时处理多个客户端的连接。这种技术通常通过`select`函数来实现,...
在Python中,常用的IO多路复用库有`select`、`poll`、`epoll`(适用于Linux)、以及` selectors`模块,这些库允许服务器同时处理多个连接,而无需等待任何一个阻塞的I/O操作完成。在这个项目中,服务器可能使用了`...
- epoll是Linux特有的高级IO多路复用技术,提供了更高效的性能。它使用epoll_ctl来添加、修改和删除文件描述符,以及epoll_wait来等待事件发生。epoll采用了“边缘触发”(ET)或“水平触发”(LT)两种模式,其中边缘...
尝试阻塞与非阻塞,IO多路复用(select,_epoll)_Socket
select是多路复用I/O的一种方式,用于监控多个文件描述符(如socket)的状态,看它们是否准备好进行读写操作。通过将文件描述符放入三个集合(readfds、writefds、exceptfds)中,select会阻塞直到至少有一个描述符...
Nginx采用的是基于事件驱动的异步非阻塞模型,它结合了多路复用技术,如Linux的`epoll`。当客户端发起请求时,Nginx将请求挂起,然后继续处理其他请求,一旦某个请求的数据准备好,Nginx会立即处理并返回结果。这种...
在IT领域,网络编程是不可或缺...总结来说,这个项目展示了如何使用Python的socket库结合多线程和IO多路复用技术来创建一个多人聊天室应用。通过理解和实践这些知识点,开发者可以提升在网络编程和并发处理方面的技能。
因此,在大型高并发的系统中,通常会使用更高效的I/O多路复用模型,如epoll(Linux)或kqueue(FreeBSD)。 总之,基于select模型的Socket服务器是网络编程中处理多客户端连接的基本方法,对于理解和实践网络服务...
### Linux网络编程之IO复用循环服务器 #### 一、引言 在现代网络应用开发中,服务器的设计面临着越来越高的并发请求处理需求。传统的简单循环服务器每次只能处理一个客户端请求,这种方式显然无法满足高并发场景的...
在Linux中,有五种主要的IO模型:阻塞IO、非阻塞IO、IO复用(如select、poll、epoll)、信号驱动IO和异步IO。每种模型都有其适用场景和优缺点。例如,阻塞IO简单易用,但会阻塞进程直到数据准备就绪;非阻塞IO不会...
IO复用是一种多路复用技术,它允许一个进程同时等待多个IO操作完成,而无需为每个操作创建单独的线程或进程。这种方法显著提高了资源利用率和系统吞吐量。在Linux系统中,Epoll是实现IO复用的主要机制,相比旧有的...
`select()`函数是实现I/O多路复用的关键函数之一,其功能是让进程指示内核等待多个事件中的任意一个发生,并且只在事件发生或超时后唤醒进程。该函数的基本形式如下: ```c #include <sys/select.h> #include int...
IO多路复用是一种高效的处理多个并发连接的技术,尤其在处理大量并发的网络连接时,如SocketServer场景。当有500个链接同时连接到服务器时,如果使用单线程处理,每个连接的IO操作(如读写数据)会依次进行,导致...
总结,本压缩包提供的代码示例和讲解了select模型在socket通信中的应用,帮助开发者理解如何使用select来实现高效、多路复用的网络服务。在实际开发中,根据系统资源和需求,开发者还需要权衡select与其他I/O模型...
`select`函数是Linux提供的一种IO复用方法,它可以监控多个套接字(socket)状态,当其中任意一个套接字准备就绪时,`select`会返回,告知程序可以进行下一步处理。 在TCP网络编程中,服务器通常需要同时处理多个...
Socket编程是网络编程的核心部分,而`select`函数在多路复用IO模型中扮演着重要角色,尤其在处理大量并发连接时。本篇文章将深入探讨`select`模式在Socket编程中的应用及其工作原理。 首先,`select`是一个系统调用...
在Linux系统中,IO多路复用是一种高效的网络编程技术,它允许多个网络连接在同一时间进行处理,而不需要为每个连接创建单独的线程或进程。`epoll`是Linux内核提供的一种IO多路复用机制,特别适合于高并发、高性能的...
在类unix系统中有五大I/O模型,依次为阻塞IO(BIO)、非阻塞IO(NIO)、IO多路复用(linux下有select、poll、epoll三种方案)、信号驱动IO、异步IO(前面四种都是同步IO),本文主要介绍常用的C的IO库,几乎都是...
标题提及的“事件选择模型”是异步I/O实现的一种方式,通常包括多路复用技术,如select、poll、epoll等。这些技术允许一个单独的线程监控多个套接字,从而提高系统资源利用率并降低响应时间。 **事件选择模型:** ...