`
linguanghuan
  • 浏览: 3973 次
社区版块
存档分类
最新评论

Linux Socket select IO多路复用

 
阅读更多
#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多路复用

    在Windows环境下进行网络编程,Socket多路复用是一种高效处理多个连接请求的技术,它允许多个套接字(sockets)在同一时刻被监控,以便服务端能够同时处理多个客户端的连接。这种技术通常通过`select`函数来实现,...

    io多路复用服务器-聊天室.zip

    在Python中,常用的IO多路复用库有`select`、`poll`、`epoll`(适用于Linux)、以及` selectors`模块,这些库允许服务器同时处理多个连接,而无需等待任何一个阻塞的I/O操作完成。在这个项目中,服务器可能使用了`...

    IO多路复用图解1

    - epoll是Linux特有的高级IO多路复用技术,提供了更高效的性能。它使用epoll_ctl来添加、修改和删除文件描述符,以及epoll_wait来等待事件发生。epoll采用了“边缘触发”(ET)或“水平触发”(LT)两种模式,其中边缘...

    尝试阻塞与非阻塞,IO多路复用(select,_epoll)_Socket.zip

    尝试阻塞与非阻塞,IO多路复用(select,_epoll)_Socket

    socket select io模型传文件

    select是多路复用I/O的一种方式,用于监控多个文件描述符(如socket)的状态,看它们是否准备好进行读写操作。通过将文件描述符放入三个集合(readfds、writefds、exceptfds)中,select会阻塞直到至少有一个描述符...

    多进程&多路复用并发的http服务器

    Nginx采用的是基于事件驱动的异步非阻塞模型,它结合了多路复用技术,如Linux的`epoll`。当客户端发起请求时,Nginx将请求挂起,然后继续处理其他请求,一旦某个请求的数据准备好,Nginx会立即处理并返回结果。这种...

    基于TCP协议分别使用多线程、IO 多路复用的方法实现多人聊天室(python).zip

    在IT领域,网络编程是不可或缺...总结来说,这个项目展示了如何使用Python的socket库结合多线程和IO多路复用技术来创建一个多人聊天室应用。通过理解和实践这些知识点,开发者可以提升在网络编程和并发处理方面的技能。

    基于select模型的socket服务器

    因此,在大型高并发的系统中,通常会使用更高效的I/O多路复用模型,如epoll(Linux)或kqueue(FreeBSD)。 总之,基于select模型的Socket服务器是网络编程中处理多客户端连接的基本方法,对于理解和实践网络服务...

    Linux网络编程之IO复用循环服务器

    ### Linux网络编程之IO复用循环服务器 #### 一、引言 在现代网络应用开发中,服务器的设计面临着越来越高的并发请求处理需求。传统的简单循环服务器每次只能处理一个客户端请求,这种方式显然无法满足高并发场景的...

    Linux Socket编程、Linux IO模型、Linux 进程间通信完整用例

    在Linux中,有五种主要的IO模型:阻塞IO、非阻塞IO、IO复用(如select、poll、epoll)、信号驱动IO和异步IO。每种模型都有其适用场景和优缺点。例如,阻塞IO简单易用,但会阻塞进程直到数据准备就绪;非阻塞IO不会...

    基于io复用的服务器开发例子

    IO复用是一种多路复用技术,它允许一个进程同时等待多个IO操作完成,而无需为每个操作创建单独的线程或进程。这种方法显著提高了资源利用率和系统吞吐量。在Linux系统中,Epoll是实现IO复用的主要机制,相比旧有的...

    单线程多路复用(异步通信)

    `select()`函数是实现I/O多路复用的关键函数之一,其功能是让进程指示内核等待多个事件中的任意一个发生,并且只在事件发生或超时后唤醒进程。该函数的基本形式如下: ```c #include &lt;sys/select.h&gt; #include int...

    详解Python IO口多路复用

    IO多路复用是一种高效的处理多个并发连接的技术,尤其在处理大量并发的网络连接时,如SocketServer场景。当有500个链接同时连接到服务器时,如果使用单线程处理,每个连接的IO操作(如读写数据)会依次进行,导致...

    select_IO_model.rar_select模型_socket select

    总结,本压缩包提供的代码示例和讲解了select模型在socket通信中的应用,帮助开发者理解如何使用select来实现高效、多路复用的网络服务。在实际开发中,根据系统资源和需求,开发者还需要权衡select与其他I/O模型...

    IO复用select+多线程.rar

    `select`函数是Linux提供的一种IO复用方法,它可以监控多个套接字(socket)状态,当其中任意一个套接字准备就绪时,`select`会返回,告知程序可以进行下一步处理。 在TCP网络编程中,服务器通常需要同时处理多个...

    socket模式中的select

    Socket编程是网络编程的核心部分,而`select`函数在多路复用IO模型中扮演着重要角色,尤其在处理大量并发连接时。本篇文章将深入探讨`select`模式在Socket编程中的应用及其工作原理。 首先,`select`是一个系统调用...

    Linux IO多路复用之epoll网络编程

    在Linux系统中,IO多路复用是一种高效的网络编程技术,它允许多个网络连接在同一时间进行处理,而不需要为每个连接创建单独的线程或进程。`epoll`是Linux内核提供的一种IO多路复用机制,特别适合于高并发、高性能的...

    特征:1、跨平台(Linux, Windows, MacOS, Solaris)2、高性能事件循环.rar

        在类unix系统中有五大I/O模型,依次为阻塞IO(BIO)、非阻塞IO(NIO)、IO多路复用(linux下有select、poll、epoll三种方案)、信号驱动IO、异步IO(前面四种都是同步IO),本文主要介绍常用的C的IO库,几乎都是...

    异步IO之事件选择模型使用说明_高并发_vcsocket异步IO_

    标题提及的“事件选择模型”是异步I/O实现的一种方式,通常包括多路复用技术,如select、poll、epoll等。这些技术允许一个单独的线程监控多个套接字,从而提高系统资源利用率并降低响应时间。 **事件选择模型:** ...

Global site tag (gtag.js) - Google Analytics