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

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多路复用,select FD_SET FD_ZERO FD_ISSET FD_CLR等函数的用法,包含客户端和服务器端代码,开发环境vs2008

    详解Python IO口多路复用

    什么是IO 多路复用呢? 我一个SocketServer有500个链接连过来了,我想让500个链接都是并发的,每一个链接都需要操作IO,但是单线程下IO都是串行的,我实现多路的,看起来像是并发的效果,这就是多路复用! 概念说明...

    IO多路复用图解1

    1. 线程或者进程会消耗资源 2.线程或进程调度消耗CPU资源 1. 线程或者进程会消耗资源 2.线程或进程调度消耗CPU资源 1.每次调用select,都需要

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

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

    linux_qq.rar_QQ协议_epoll 文件_linux socket epoll_linux项目_socket好友聊天

    包括服务器端和客户端两部分,其中客户端使用了select的IO多路复用技术,服务器端由于要监听多个客户端,因此使用了epoll的IO多路复用技术。整个项目目前可以实现的功能有用户的注册与登录,添加好友,发送聊天消息...

    Linux IO的水平触发和边缘触发的区别

     在linux的IO多路复用中有水平触发,边缘触发两种模式,这两种模式的区别如下:  水平触发:如果文件描述符已经就绪可以非阻塞的执行IO操作了,此时会触发通知.允许在任意时刻重复检测IO的状态.select,poll就属于水平...

    python 并发编程 多路复用IO模型详解

    多路复用IO(IO multiplexing) 这种IO方式为事件驱动IO(event driven IO)。 我们都知道,select/epoll的好处就在于单个进程process就可以同时处理多个网络连接的IO。它的基本原理就是select/epoll这个function会不断...

    本项目包括利用多线程、select、poll以及epoll实现的并发处理连接请求

    这两类都要使用到IO多路复用,O多路复用是指单个进程/线程就可以同时处理多个IO请求。有三个方式select、poll、epoll。 select:将文件描述符放入一个集合中,调用select时,将这个集合从用户空间拷贝到内核空间...

    socket_select.zip

    select系统调用的的用途是:在一段指定的时间内,监听用户感兴趣的文件描述符上可读、可写和异常等事件。 实现基于select的io复用单服务器多客户端socket通信。

    Python之进程+线程+协程(异步、selectors模块、阻塞、非阻塞IO)

    本篇文字是关于IO多路复用的更深入一步的总结,上一篇Python之进程+线程+协程(事件驱动模型、IO多路复用、select与epoll)对IO多路复用进行了概念性的分析,本篇则是对阻塞IO、非阻塞IO、与异步进行通俗性的比较和...

    linux epoll机制详解

    在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序。在linux新的内核中,有了一种替换它的机制,就是epoll。 select()和poll() IO多路复用模型 select的...

    200行自定义python异步非阻塞Web框架

    本文基于非阻塞的Socket以及IO多路复用从而实现异步非阻塞的Web框架,其中便是众多异步非阻塞Web框架内部原理。 #!/usr/bin/env python # -*- coding:utf-8 -*- import re import socket import select import time...

    IO复用:select,poll,epoll,kqueue的详细例子

    源码详解文章地址 https://blog.csdn.net/yadoufeng/article/details/130443058?spm=1001.2014.3001.5502

    C++开发基于TCPsocket实现的web服务器源码.zip

    3、通过select实现io复用,并检测是否有可读或者可写的文件描述符到来(也就是有无客户端连接到来); 4、当有连接到来时,调用accept函数,将客户端套接字与服务器套接字组成新的会话,并将会话添加到会话socket...

    Linux高性能服务器编程

    8.5.1 半同步半异步模式 8.5.2 领导者追随者模式 8.6 有限状态机 8.7 提高服务器性能的其他建议 8.7.1 池 8.7.2 数据复制 8.7.3 上下文切换和锁 第9章 IO复用 9.1 select系统调用 9.1.1 select API 9.1.2...

    Python313道企业面试题集锦(附答案).pdf

    (属于多路复用 IO 的模型). 90.什么是防火墙以及作用?. 91.简述 进程、线程、协程的区别 以及应用场景?. 92.GIL 锁是什么? 93.Python 中如何使用线程池和进程池? 94.threading.local 的作用? 95.进程...

    libevent参考手册(中文版P

    * 支持多种 I/O多路复用技术, epoll、poll、dev/poll、select 和kqueue 等; * 支持 I/O,定时器和信号等事件; libevent有下面几大部分组成: * 事件管理包括各种IO(socket)、定时器、信号等事件,也是...

    Linux局域网聊天项目

    采用C/S架构,主函数在template\localChat下,客户端client.c和服务端server.c。 template下Makefile进行的是lib和...主要知识点:socket套接字、链表用户管理、线程创建管理、IO复用、select监听套接字、文件读写等。

    I-O复用与套接口选项

    I/O Models I/O multiplexing concept Select and pselect functions Socket options Nonblocking IO Signal-driven IO

    linux网络编程-宋敬彬-part1

    9.3.3 IO复用 257 9.3.4 信号驱动IO模型 258 9.3.5 异步IO模型 258 9.4 select()函数和pselect()函数 259 9.4.1 select()函数 259 9.4.2 pselect()函数 261 9.5 poll()函数和ppoll()函数 262 9.5.1 ...

Global site tag (gtag.js) - Google Analytics