select server
server with select
#include<stdio.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<unistd.h>
#include<stdlib.h>
#include<errno.h>
#include<arpa/inet.h>
#include<netinet/in.h>
#include<string.h>
#include<signal.h>
#include<sys/wait.h> #define ERR_EXIT(m) \
do { \
perror(m); \
exit(EXIT_FAILURE); \
} while () int main(void)
{ signal(SIGPIPE, SIG_IGN);
int listenfd; //被动套接字(文件描述符),即只可以accept, 监听套接字
if ((listenfd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < )
// listenfd = socket(AF_INET, SOCK_STREAM, 0)
ERR_EXIT("socket error"); struct sockaddr_in servaddr;
memset(&servaddr, , sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons();
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
/* servaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); */
/* inet_aton("127.0.0.1", &servaddr.sin_addr); */ int on = ;
if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < )
ERR_EXIT("setsockopt error"); if (bind(listenfd, (struct sockaddr*)&servaddr,sizeof(servaddr)) < )
ERR_EXIT("bind error"); if (listen(listenfd, SOMAXCONN) < ) //listen应在socket和bind之后,而在accept之前
ERR_EXIT("listen error"); struct sockaddr_in peeraddr; //传出参数
socklen_t peerlen = sizeof(peeraddr); //传入传出参数,必须有初始值 int conn; // 已连接套接字(变为主动套接字,即可以主动connect)
int i;
int client[FD_SETSIZE];
int maxi = ; // client数组中最大不空闲位置的下标
for (i = ; i < FD_SETSIZE; i++)
client[i] = -; int nready;
int maxfd = listenfd;
fd_set rset;
fd_set allset;
FD_ZERO(&rset);
FD_ZERO(&allset);
FD_SET(listenfd, &allset); while () {
rset = allset;
nready = select(maxfd + , &rset, NULL, NULL, NULL);
if (nready == -) {
if (errno == EINTR)
continue;
ERR_EXIT("select error");
} if (nready == )
continue; if (FD_ISSET(listenfd, &rset)) { conn = accept(listenfd, (struct sockaddr*)&peeraddr, &peerlen); //accept不再阻塞
if (conn == -)
ERR_EXIT("accept error"); for (i = ; i < FD_SETSIZE; i++) {
if (client[i] < ) {
client[i] = conn;
if (i > maxi)
maxi = i;
break;
}
} if (i == FD_SETSIZE) {
fprintf(stderr, "too many clients\n");
exit(EXIT_FAILURE);
} printf("recv connect ip=%s port=%d\n", inet_ntoa(peeraddr.sin_addr),
ntohs(peeraddr.sin_port)); FD_SET(conn, &allset);
if (conn > maxfd)
maxfd = conn; if (--nready <= )
continue;
} for (i = ; i <= maxi; i++) {
conn = client[i];
if (conn == -)
continue; if (FD_ISSET(conn, &rset)) { char recvbuf[] = {};
int ret = read(conn, recvbuf, );
if (ret == -)
ERR_EXIT("readline error");
else if (ret == ) { //客户端关闭
printf("client close \n");
FD_CLR(conn, &allset);
client[i] = -;
close(conn);
} fputs(recvbuf, stdout);
write(conn, recvbuf, strlen(recvbuf)); if (--nready <= )
break;
}
} } return ;
}
select server的更多相关文章
- Winsock select server 与 client 示例代码
参考 https://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancediomethod5.html ...
- 用SQL Server(T-SQL)获取连接字符串
一般情况下,C# 连接SQL Server的字符串可以直接按照说明文档直接手动写出来,或者也可以参考大名鼎鼎的connectionstrings手动拼写 但是如果你已经连接到SQL Server也可以 ...
- Windows Server 2012 虚拟化实战:域
在Windows Server系统中,一些服务必需要构建在域的环境中,这不仅是为了统一验证和资源共享,同时也是为了网络安全.为构建虚拟化测试,我们需要先搭建域环境.之前先来大概了解一下域. 在使用工作 ...
- SQL Server 数据库巡检脚本
--1.查看数据库版本信息 select @@version --2.查看所有数据库名称及大小 exec sp_helpdb --3.查看数据库所在机器的操作系统参数 exec master..xp_ ...
- [转]Installing SharePoint 2013 on Windows Server 2012 R2
转自:http://www.avivroth.com/2013/07/09/installing-sharepoint-2013-on-windows-server-2012-r2-preview/ ...
- 第十天 多进程、协程(multiprocessing、greenlet、gevent、gevent.monkey、select、selector)
1.多进程实现方式(类似于多线程) import multiprocessing import time,threading def thread_run():#定义一个线程函数 print(&quo ...
- Windows Server 2008 R2 辅域控制器如何升级成主域控制器
一.实验模拟故障问题: zhuyu公司架设了一台主域控制器和一台辅域控制器,某一天,zhuyu公司的主域控制器系统崩溃,主域控制器系统也进不去. 虽然辅域控制器可以暂时代替主域控制器的普通工作,但是特 ...
- Python网络编程(4)——异步编程select & epoll
在SocketServer模块的学习中,我们了解了多线程和多进程简单Server的实现,使用多线程.多进程技术的服务端为每一个新的client连接创建一个新的进/线程,当client数量较多时,这种技 ...
- 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】
下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...
随机推荐
- Unity 依赖注入
关于Ioc的框架有很多,比如astle Windsor.Unity.Spring.NET.StructureMap,我们这边使用微软提供的Unity做示例,你可以使用Nuget添加Unity,也可以引 ...
- PHP在 win7 64位 旗舰版 报错 Call to undefined function curl_init()
代码在ubuntu下无缝运行OK 转到我的win7 64位 期间 学习机上 报错: Call to undefined function curl_init() 因为用到curl 远程抓取数据. 所以 ...
- Android中Handler的使用方法及实例(基础回顾)
Handler使用例1 这个例子是最简单的介绍handler使用的,是将handler绑定到它所建立的线程中.本次实验完成的功能是:单击Start按钮,程序会开始启动线程,并且线程程序完成后延时1s会 ...
- MongoDB日志文件过大
MongoDB日志文件过大 MongoDB启动的时候指定了--logpath为一个日志文件.随着时间此文件会变得越来越大,达到好几个G. 因为不想让MongoDB进程重新启动,所以不能停止进程删除此文 ...
- PHP之mb_internal_encoding使用
mb_internal_encoding (PHP 4 >= 4.0.6, PHP 5, PHP 7) mb_internal_encoding - Set/Get internal chara ...
- Java 中 String 的常用方法(一)
上一篇介绍了 String 中的几个常用构造方法,由 String 这个核心对象发散出去关于字符的编码,字符的字节表达,对 GC 的影响,正则表达式,模式匹配,这可能是 Java 里内涵最丰富的对象了 ...
- [中英对照]How PCI Works | PCI工作原理
How PCI Works | PCI工作原理 Your computer's components work together through a bus. Learn about the PCI ...
- 09 jdk1.5的并发容器:CopyOnWriteArrayList(转载)
原文链接:http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略. 其基本思路是,从一开始大家都在共享同一个内容 ...
- python实例:元组命名 频次统计 字典排序
1.为元组中元素命名 方法1.定义常量 NAME, AGE = 0, 1 student = ('乔峰', 29, 'qf@jinyong.com') name = student[NAME] age ...
- Elastic Kibana - Install as windows service
#1 通过windows sc 服务命令安装 sc create "Kibana661" binPath= "{path}\kibana.bat" depend ...