当我们用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. 【LeetCode】Counting Bits(338)

    1. Description Given a non negative integer number num. For every numbers i in the range 0 ≤ i ≤ num ...

  2. 以太坊智能合约Hello World示例程序

    简介 以太坊(Ethereum)是一提供个智能合约(smart contract)功能的公共区块链(BlockChain)平台. 本文介绍了一个简单的以太坊智能合约的开发过程. 开发环境 在以太坊上开 ...

  3. springmvc处理上传图片代码(校验图片尺寸、图片大小)

    package com.maizuo.web.controller; import com.maizuo.domain.Result; import com.maizuo.util.Constants ...

  4. XML 动态 插入 父类标示 子类标示

    由于第一次写博客,写的不好的地方,还请各位大神多多指点, 讲解一下:xml动态插入数据并保存,写这个时候费了我不少劲,最后终于皇天不负有心人让我搞出来了,特意分享给大家,写的不完美的地方还请大家多多指 ...

  5. 【配置属性】—Entity Framework 对应表字段的类型的设定配置方法

    摘自:http://www.cnblogs.com/nianming/archive/2012/11/07/2757997.html Entity Framework Code First的默认行为是 ...

  6. qam 64的设计

    module qam64(x,out,clk,clk1,rst);input x,clk,clk1,rst;output [18:0] out;reg [2:0] count;reg [5:0] re ...

  7. 【linux草鞋应用编程系列】_4_ 应用程序多线程

    一.应用程序多线程     当一个计算机上具有多个CPU核心的时候,每个CPU核心都可以执行代码,此时如果使用单线程,那么这个线程只能在一个 CPU上运行,那么其他的CPU核心就处于空闲状态,浪费了系 ...

  8. HttpClient通过Post上传多个文件

    public static String sendFilesPost(String url, String fileNames) { HttpClient httpClient = null; Htt ...

  9. 使用jenkins配置.net mvc网站进行持续集成二

    上一篇使用jenkins配置.net mvc网站进行持续集成一只是简单介绍了jenkins构建站点到本地服务器,这一篇,就来讲解如何部署站点到指定的服务器上面. 1.IIS远程发布配置 1.在服务器管 ...

  10. Linux(五)__硬盘分区

    Linux中的文件管理机制是一种叫挂载和卸载的方式使用分区中的文件. 1.硬盘分区的概念 概述:首先我们要对硬盘分区的基本概念进行一些初步的了解,硬盘的分区主要分为基本分区(Primary Parti ...