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 ;
}

ref1      ref2

select server的更多相关文章

  1. Winsock select server 与 client 示例代码

    参考 https://www.winsocketdotnetworkprogramming.com/winsock2programming/winsock2advancediomethod5.html ...

  2. 用SQL Server(T-SQL)获取连接字符串

    一般情况下,C# 连接SQL Server的字符串可以直接按照说明文档直接手动写出来,或者也可以参考大名鼎鼎的connectionstrings手动拼写 但是如果你已经连接到SQL Server也可以 ...

  3. Windows Server 2012 虚拟化实战:域

    在Windows Server系统中,一些服务必需要构建在域的环境中,这不仅是为了统一验证和资源共享,同时也是为了网络安全.为构建虚拟化测试,我们需要先搭建域环境.之前先来大概了解一下域. 在使用工作 ...

  4. SQL Server 数据库巡检脚本

    --1.查看数据库版本信息 select @@version --2.查看所有数据库名称及大小 exec sp_helpdb --3.查看数据库所在机器的操作系统参数 exec master..xp_ ...

  5. [转]Installing SharePoint 2013 on Windows Server 2012 R2

    转自:http://www.avivroth.com/2013/07/09/installing-sharepoint-2013-on-windows-server-2012-r2-preview/ ...

  6. 第十天 多进程、协程(multiprocessing、greenlet、gevent、gevent.monkey、select、selector)

    1.多进程实现方式(类似于多线程) import multiprocessing import time,threading def thread_run():#定义一个线程函数 print(&quo ...

  7. Windows Server 2008 R2 辅域控制器如何升级成主域控制器

    一.实验模拟故障问题: zhuyu公司架设了一台主域控制器和一台辅域控制器,某一天,zhuyu公司的主域控制器系统崩溃,主域控制器系统也进不去. 虽然辅域控制器可以暂时代替主域控制器的普通工作,但是特 ...

  8. Python网络编程(4)——异步编程select & epoll

    在SocketServer模块的学习中,我们了解了多线程和多进程简单Server的实现,使用多线程.多进程技术的服务端为每一个新的client连接创建一个新的进/线程,当client数量较多时,这种技 ...

  9. 转一贴,今天实在写累了,也看累了--【Python异步非阻塞IO多路复用Select/Poll/Epoll使用】

    下面这篇,原理理解了, 再结合 这一周来的心得体会,整个框架就差不多了... http://www.haiyun.me/archives/1056.html 有许多封装好的异步非阻塞IO多路复用框架, ...

随机推荐

  1. (转)mysql主从切换步骤

    原文:http://6226001001.blog.51cto.com/9243584/1723273 1> 正常切换 1)从服务器检查SHOW PROCESSLIST语句的输出,直到你看到Ha ...

  2. JS框架设计之对象数组化一种子模块

    类数组对象是一个很好的存储结构,但是功能太弱了,为了享受纯数组的哪些便捷的方法,使用前可以做下转换,通常可以使用$.slice.call()方法做转换,但是旧版本的IE下的HTMLCollection ...

  3. Jmeter创建FTP测试计划

    创建FTP测试计划 在这一章,你将学习如何创建一个基础的测试计划来测试FTP站点.你将在一个FTP站点上的两个文件中创建四个用户来发送请求.并且,你将告诉用户运行测试两次.所以,总的请求数是(4个用户 ...

  4. [问题解决]Fresco设置圆角效果不生效问题探究

    [问题解决]Fresco设置圆角效果不生效问题探究 /** * Created by diql on 2017/2/21 11:07:04. */ 问题 在View中设置: fresco:rounde ...

  5. JMS、AMQP和MQTT主要特性

    今天无意中看到mq的原理,才发现activeMq与ribbMq的原理是不一样的.前者是JMS的实现,后者是AMQP的实现... 原理简介:https://www.cnblogs.com/zhangyu ...

  6. linux进程间的网络通信

    一.进程是如何进行网络通信的?socket通信的过程? 同一机器上的不同进程之间的通信方式有很多种,主要使用消息传递或共享内存.而跨网络的进程是几乎都是使用socket通信,例如web服务器,QQ. ...

  7. 虹软人脸识别在 linux中so文件加载不到的问题

    其实是可以加载到的,不过是so文件放的位置不一对,最简单的方式是放在 /usr/lib64 目录下,也可自己设置. so文件加载不到会报这个错误:    .lang.UnsatisfiedLinkEr ...

  8. 嵌套div的margin-top不生效

    之前遇到过嵌套div设置margin-top不生效的情况,一直没去研究,今天又遇到了,查阅资料得知原因,并不是margin-top没生效,只是当外层容器跟内层容器之间没有别的元素的时候,内层容器的ma ...

  9. 利用OC对象的消息重定向forwardingTargetForSelector方法构建高扩展性的滤镜功能

    在OC中,当像一个对象发送消息,而对象找到消息后,从它的类方法列表,父类方法列表,一直找到根类方法列表都没有找到与这个选择子对应的函数指针.那么这个对象就会触发消息转发机制. OC对象的继承链和isa ...

  10. MVC缓存(二)

    依赖缓存: 1.监视特定的数据库表,当数据库表里数据发生变化时,自动删除缓存项,并向Cache中添加新的项. using System; using System.Collections.Generi ...