Linux 服务器模型小结
当我们用socket进行编程的时候,细节上都是选择一个AF_LOCAL,AF_INET再根据相应的类型填充地址,其实根据通信需求,有几种简单的服务模型可供选用,掌握了这些框架再结合socket高度的抽象,可以为我们编写简单的服务器程序提供指导
循环服务
用户请求服务需要排队,服务器一次只能服务一个客户,服务完才能对下一个客户进行服务。ATM机就是这个1vs1模型。udp服务器也经常使用这个模型
//模型伪代码
main{
//获得侦听文件描述符
listenfd=socket();
//准备地址addr
//(listenfd,100);
while(1){将服务器的addr和listenfd绑定
bind(listenfd,addr)
//开始侦听,设置缓冲队列长度
listen(listenfd,100);
while(1){
//如果侦听到任务就获取sockfd
int sockfd = accept(listenfd); //listenfd默认是阻塞IO,没任务时进程会sleep
//通信...
close(sockfd);
}
}
多进程并发服务
多进程只是放listen到请求的时候,不是在原进程中处理请求,而是在子进程中处理,父进程继续侦听请求。多进程的好处父进程不必等待子进程处理完一个请求才能获取下一个请求,而是只要有请求就fork一个子进程处理,这样就可以实现并发服务器。多进程并发的更实际的方案是使用进程池来实现。
//模型伪代码
main{
//获得侦听文件描述符
listenfd=socket();
//准备地址addr
//将服务器的addr和listenfd绑定
bind(listenfd,addr)
//开始侦听,设/准备地址add置缓冲队列长度
listen(listenfd,100);
while(1){
//如果侦听到任务就获取sockfd
int sockfd = accept(listenfd); //listenfd默认是阻塞IO,没任务时进程会sleep
pid=fork();
if(0 == pid){
//子进程一定要首先关闭listenfd,防止和父进程一起侦听
//也可以在父进程socket(,,SOCK_CLOEXEC);
close(listenfd);
while(1){
ret=read(sockfd);
if(0 == ret) break;
//通信...
}
exit(0);
}
}
}
多线程并发服务
使用多线程实现并发和多进程类似,但是创建一个线程的开销比创建一个进程小得多,需要注意的是使用多线程需要做好对临界资源的保护。实际操作经常使用线程池来实现多线程并发服务。
//模型伪代码
void* communicate(void* arg){
int sockfd=(int)arg;
while(1){
ret=read(sockfd);
if(0 == ret) break;
//通信...
}
}
main{
//获得侦听文件描述符
listenfd=socket();
//准备地址addr
//将服务器的addr和listenfd绑定
bind(listenfd,addr)
//开始侦听,设置缓冲队列长度
listen(listenfd,100);
while(1){
//如果侦听到任务就获取sockfd
//listenfd默认是阻塞IO,没任务时进程会sleep
int sockfd = accept(listenfd);
pthread_create(tid,communicate,(void*)&sockfd);
}
}
}
I/O多路复用并发服务
I/O多路复用实现并发服务我已经在Linux I/O多路复用一文中举出了详细的例子,其实质就是将udp服务器的循环模型用在tcp上。
//模型伪代码
main{
//获得侦听文件描述符
listenfd=socket();
//准备地址addr
//将服务器的addr和listenfd绑定
bind(listenfd,addr)
//开始侦听,设置缓冲队列长度
listen(listenfd,100);
//准备侦听对象,和相应的触发事件的集合
monitor_set_1[i]={fds...} //监控I/O有数据流入
monitor_set_2[i]={fds...} //监控I/O变得可写
while(1){
//监控对象,如果有事件发生就返回
poll(monitor_set_1,monitor_set_2)
for(n=0;n<maxfd;n++){ //poll返回,说明有(一些)事件被触发,依次处理这些触发了事件的文件描述符
if(一个fd有数据流入){
if(是listenfd有数据流入){
//获取sockfd
int sockfd = accept(listenfd)
//将这个sockfd加入监听有数据流入可写的集合
add_mem(moniter_set_1,sockfd)
}else { //不是listenfd有数据流入,而是之前加入的sockfd有数据流入
//读取信息
read(fd,&msg)
//将其挪入加入监控可写事件的集合
add_mem(monitor_set_1,fd)
}
}else{ //一个fd变得可写了
//写入信息
write(fd,&msg)
//将其挪入监控可读的集合
add_mem(monitor_set_1,fd)
}
}
}
}
}
Linux 服务器模型小结的更多相关文章
- 常用Linux命令小结
常用Linux命令小结 Linux下有很多常用的很有用的命令,这种命令用的多了就熟了,对于我来说,如果长时间没有用的话,就容易忘记.当然,可以到时候用man命令查看帮助,但是,到时候查找的话未免有些临 ...
- linux命令小结
查看IP ip a 测试ip ping 10.0.0.128 测试端口 telnet 10.0.0.128 22 # telnet + ip + 端口 Linux - CentOS 7. ...
- 高频Linux命令小结(新手向)
示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 近期 ...
- Linux指令小结
1.apt指令集:是ubuntu中最强大的命令行软件管理工具,用于获取.安装.编译.卸载和查询软件包.还可以检查软件包的依赖关系.在ubunt中下载是根据/etc/apt/sources.list这个 ...
- Linux命令小结:fdisk
查看分区信息 分区信息包括容量.扇区数目.柱面数目.磁头数目和IO大小等信息. root@cvm:/# fdisk -l /dev/sda7 Disk /dev/sda7: 441.8 GB, 441 ...
- 【LINUX】Linux学习小结
****xargs命令**** 当需要将参数列表转换成小块分段传递给其他命令时,可以使用xargs命令.栗子如下: 若想在启动lampp之后用kill方式杀掉全部的进程就可以用下面的命令: ps -e ...
- Linux学习小结(转)
linux目录架构 / 根目录/bin 常用的命令 binary file 的目錄/boot 存放系统启动时必须读取的档案,包括核心 (kernel) 在内/boot/grub/menu.l ...
- linux 命令小结
chkconfig --list 查询所有服务运行情况 修改文件夹权限: 在Linux中,权限的所有者分为用户权限,组权限和其他权限,分别是用字母u, g, o 代表权限分为:读 r , 写 w , ...
- 嵌入式Linux学习小结
这两个月一直在学习Linux.作为一名刚開始学习的人,学习期间难免磕磕碰碰.走弯路,可是,抱着不怕失败.多尝试的信念,终于还是坚持下来了. 如今已经清楚Linux的框架,知道怎么去开发一个Linux程 ...
随机推荐
- HTML5+CSS3实现图片可倾斜摆放的动画相册效果
先看看效果:其中鼠标悬浮在图片上会有动态效果图 直接上代码: css文件 @CHARSET "UTF-8"; *{ padding:0px; margin:0px; } div{ ...
- js构建ui的统一异常处理方案(一)
从早期从事基于java的服务器端开发,再到之后从事基于web和js的ui开发,总体感觉基于web页面的ui开发远不如服务器端健壮.主要是早期ie浏览器功能太弱小,很多业务被迫放到服务器端去实现,浏览器 ...
- Spring Boot文档阅读
原因之初 最初习惯百度各种博客教程,然后跟着操作,因为觉得跟着别人走过的路走可以少走很多弯路,省时间.然而,很多博客的内容并不够完整,甚至错误,看多了的博客甚至有千篇一律的感觉.此外,博客毕竟是记载博 ...
- 使用webstom或者idea上传代码到github或coding
鉴于github网络速度太慢,建议用coding.先介绍github上传方式,因为webstom或idea集成了github,方法简单. git是一个版本控制器,他的作用是管理代码.比如你修改了代码, ...
- scikit-learn一般实例之三:连接多个特征提取方法
在很多现实世界的例子中,有很多从数据集中提取特征的方法.很多时候我们需要结合多种方法获得好的效果.本例将展示怎样使用FeatureUnion通过主成分分析和单变量选择相进行特征结合. 结合使用转换器的 ...
- 关于C#操作防火墙,阻止程序联网
//开启服务.开启防火墙 public void OpenFileWall() { // 1. 判断当前系统为XP或Win7 RegistryKey rk = Registry.LocalMachin ...
- EC笔记,第二部分:7.为多态基类声明虚析构函数
7.为多态基类声明虚析构函数 1.为多态基类声明虚析构函数 code1: class A{ public: int* a; A():a(new int(5)) {} ~A(){ delete a; } ...
- nodejs:连接数据库SqlServer,mssql模块
现在的数据库越来越多,如mgdb,我比较常用的是mysql,但有一天做项目需要连接SqlServer,就去找了个方法.找了很多无非就mssql模块和node-sqlserver模块,但node-sql ...
- hibernate配置文件hibernate.cfg.xml和.hbm.xml的详细解释
原文地址:http://blog.csdn.net/qiaqia609/article/details/9456489 hibernate.cfg.xml -标准的XML文件的起始行,version= ...
- ABP之动态WebAPI(一)
ABP的动态WebApi实现了直接对服务层的调用(其实病没有跨过ApiController,只是将ApiController公共化,对于这一点的处理类似于MVC,对服务端的 调用没有跨过HttpHan ...