当我们用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 服务器模型小结的更多相关文章

  1. 常用Linux命令小结

    常用Linux命令小结 Linux下有很多常用的很有用的命令,这种命令用的多了就熟了,对于我来说,如果长时间没有用的话,就容易忘记.当然,可以到时候用man命令查看帮助,但是,到时候查找的话未免有些临 ...

  2. linux命令小结

    查看IP  ip a 测试ip   ping 10.0.0.128 测试端口   telnet 10.0.0.128  22  # telnet + ip + 端口 Linux - CentOS 7. ...

  3. 高频Linux命令小结(新手向)

    示例代码托管在:http://www.github.com/dashnowords/blogs 博客园地址:<大史住在大前端>原创博文目录 华为云社区地址:[你要的前端打怪升级指南] 近期 ...

  4. Linux指令小结

    1.apt指令集:是ubuntu中最强大的命令行软件管理工具,用于获取.安装.编译.卸载和查询软件包.还可以检查软件包的依赖关系.在ubunt中下载是根据/etc/apt/sources.list这个 ...

  5. Linux命令小结:fdisk

    查看分区信息 分区信息包括容量.扇区数目.柱面数目.磁头数目和IO大小等信息. root@cvm:/# fdisk -l /dev/sda7 Disk /dev/sda7: 441.8 GB, 441 ...

  6. 【LINUX】Linux学习小结

    ****xargs命令**** 当需要将参数列表转换成小块分段传递给其他命令时,可以使用xargs命令.栗子如下: 若想在启动lampp之后用kill方式杀掉全部的进程就可以用下面的命令: ps -e ...

  7. Linux学习小结(转)

    linux目录架构 / 根目录/bin    常用的命令 binary file 的目錄/boot   存放系统启动时必须读取的档案,包括核心 (kernel) 在内/boot/grub/menu.l ...

  8. linux 命令小结

    chkconfig --list  查询所有服务运行情况 修改文件夹权限: 在Linux中,权限的所有者分为用户权限,组权限和其他权限,分别是用字母u, g, o 代表权限分为:读 r , 写 w , ...

  9. 嵌入式Linux学习小结

    这两个月一直在学习Linux.作为一名刚開始学习的人,学习期间难免磕磕碰碰.走弯路,可是,抱着不怕失败.多尝试的信念,终于还是坚持下来了. 如今已经清楚Linux的框架,知道怎么去开发一个Linux程 ...

随机推荐

  1. Service组件简介

    Service是一个应用程序组件,没有图形化界面,通常用来处理一些耗时较长的操作,可以用Service更新ContentProvider,发送Intent以及启动系统的通知等等.Service并不是一 ...

  2. 【知识积累】SBT+Scala+MySQL的Demo

    一.背景 由于项目需要,需要在Sbt+Scala项目中连接MySQL数据库.由于之前使用Maven+Java进行依赖管理偏多,在Sbt+Scala方面也在不断进行摸索,特此记录,作为小模块知识的积累. ...

  3. js构建ui的统一异常处理方案(四)

    上一篇我们介绍了统一异常处理方案的设计方案,这一篇我们将直接做一个小例子,验证我们的设计方案. 例子是一个todo的列表界面(页面代码参考于https://github.com/zongxiao/Dj ...

  4. 归一化变换 Normalizing transformations

    归一化变换包含两个部分,图像坐标的平移和尺度的缩放.进行归一化的变换不但能够提高处理结果的精确度,而且通过选择一个标准的坐标系预先的消除了图像尺度和坐标原点的选择对算法最终结果的影响. 归一化变换的步 ...

  5. jQuery-1.9.1源码分析系列(一)整体架构

    不废话,直接上关键.这个系列中有好些直接借用别人的资料,我将他们整合在自认为比较合理的地方.所以在此先谢谢那些前辈. 注意:后续系列中jQuery实例多用$(...)来表示 1.    初始化与链式调 ...

  6. 设计模式(Design Pattern)系列之.NET专题

    最近,不是特别忙,重新翻了下设计模式,特地在此记录一下.会不定期更新本系列专题文章. 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结. 使用 ...

  7. R语言数据处理包dplyr、tidyr笔记

    dplyr包是Hadley Wickham的新作,主要用于数据清洗和整理,该包专注dataframe数据格式,从而大幅提高了数据处理速度,并且提供了与其它数据库的接口:tidyr包的作者是Hadley ...

  8. [连载]《C#通讯(串口和网络)框架的设计与实现》-4.设备驱动管理器的设计

    目       录 第四章           设备驱动管理器的设计... 2 4.1           接口定义... 2 4.2           设备容器... 7 4.3          ...

  9. jQuery:详解jQuery中的事件(二)

    上一篇讲到jQuery中的事件,深入学习了加载DOM和事件绑定的相关知识,这篇主要深入讨论jQuery事件中的合成事件.事件冒泡和事件移除等内容. 接上篇jQuery:详解jQuery中的事件(一) ...

  10. js无限级树菜单

    以前做网站,树形菜单一般都很简单,自己定义风格样式,简单的js控制,后来原来网上很多文章都在讨论Js树型菜单,看了几个实例,发现这个树比较简单好用. http://hovertree.com/texi ...