#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多路复用,select FD_SET FD_ZERO FD_ISSET FD_CLR等函数的用法,包含客户端和服务器端代码,开发环境vs2008
什么是IO 多路复用呢? 我一个SocketServer有500个链接连过来了,我想让500个链接都是并发的,每一个链接都需要操作IO,但是单线程下IO都是串行的,我实现多路的,看起来像是并发的效果,这就是多路复用! 概念说明...
1. 线程或者进程会消耗资源 2.线程或进程调度消耗CPU资源 1. 线程或者进程会消耗资源 2.线程或进程调度消耗CPU资源 1.每次调用select,都需要
在类unix系统中有五大I/O模型,依次为阻塞IO(BIO)、非阻塞IO(NIO)、IO多路复用(linux下有select、poll、epoll三种方案)、信号驱动IO、异步IO(前面四种都是同步IO),本文主要介绍常用的C的IO库,几乎都是...
包括服务器端和客户端两部分,其中客户端使用了select的IO多路复用技术,服务器端由于要监听多个客户端,因此使用了epoll的IO多路复用技术。整个项目目前可以实现的功能有用户的注册与登录,添加好友,发送聊天消息...
在linux的IO多路复用中有水平触发,边缘触发两种模式,这两种模式的区别如下: 水平触发:如果文件描述符已经就绪可以非阻塞的执行IO操作了,此时会触发通知.允许在任意时刻重复检测IO的状态.select,poll就属于水平...
多路复用IO(IO multiplexing) 这种IO方式为事件驱动IO(event driven IO)。 我们都知道,select/epoll的好处就在于单个进程process就可以同时处理多个网络连接的IO。它的基本原理就是select/epoll这个function会不断...
这两类都要使用到IO多路复用,O多路复用是指单个进程/线程就可以同时处理多个IO请求。有三个方式select、poll、epoll。 select:将文件描述符放入一个集合中,调用select时,将这个集合从用户空间拷贝到内核空间...
select系统调用的的用途是:在一段指定的时间内,监听用户感兴趣的文件描述符上可读、可写和异常等事件。 实现基于select的io复用单服务器多客户端socket通信。
本篇文字是关于IO多路复用的更深入一步的总结,上一篇Python之进程+线程+协程(事件驱动模型、IO多路复用、select与epoll)对IO多路复用进行了概念性的分析,本篇则是对阻塞IO、非阻塞IO、与异步进行通俗性的比较和...
在linux 没有实现epoll事件驱动机制之前,我们一般选择用select或者poll等IO多路复用的方法来实现并发服务程序。在linux新的内核中,有了一种替换它的机制,就是epoll。 select()和poll() IO多路复用模型 select的...
本文基于非阻塞的Socket以及IO多路复用从而实现异步非阻塞的Web框架,其中便是众多异步非阻塞Web框架内部原理。 #!/usr/bin/env python # -*- coding:utf-8 -*- import re import socket import select import time...
源码详解文章地址 https://blog.csdn.net/yadoufeng/article/details/130443058?spm=1001.2014.3001.5502
3、通过select实现io复用,并检测是否有可读或者可写的文件描述符到来(也就是有无客户端连接到来); 4、当有连接到来时,调用accept函数,将客户端套接字与服务器套接字组成新的会话,并将会话添加到会话socket...
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...
(属于多路复用 IO 的模型). 90.什么是防火墙以及作用?. 91.简述 进程、线程、协程的区别 以及应用场景?. 92.GIL 锁是什么? 93.Python 中如何使用线程池和进程池? 94.threading.local 的作用? 95.进程...
* 支持多种 I/O多路复用技术, epoll、poll、dev/poll、select 和kqueue 等; * 支持 I/O,定时器和信号等事件; libevent有下面几大部分组成: * 事件管理包括各种IO(socket)、定时器、信号等事件,也是...
采用C/S架构,主函数在template\localChat下,客户端client.c和服务端server.c。 template下Makefile进行的是lib和...主要知识点:socket套接字、链表用户管理、线程创建管理、IO复用、select监听套接字、文件读写等。
I/O Models I/O multiplexing concept Select and pselect functions Socket options Nonblocking IO Signal-driven IO
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 ...