当我们用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. ajax调用本地wcf中的post和get

    我们可以通过jQuery调用本地或者远程的wcf服务,本文讲解的是对本地wcf服务的post和get调用方式. post和get到底有什么区别呢?此处不作详述. 但是,post对请求的数据格式更为严格 ...

  2. PHP中常见魔术方法解析

    <?php class info { private $province; //省 public $city; //城市 private $myname; //姓名 //__construct( ...

  3. ThinkPHP学习(二)

    开发规范 1.命名规范 使用ThinkPHP开发的过程中应该尽量遵循下列命名规范: 特例:在ThinkPHP里面,有一个函数命名的特例,就是单字母大写函数,这类函数通常是某些操作的快 捷定义,或者有特 ...

  4. Go语言异常处理defer\panic\recover

    Go语言追求简洁优雅,所以,Go语言不支持传统的 try…catch…finally 这种异常,因为Go语言的设计者们认为,将异常与控制结构混在一起会很容易使得代码变得混乱.因为开发者很容易滥用异常, ...

  5. MyBatis入门基础(一)

    一:对原生态JDBC问题的总结 新项目要使用mybatis作为持久层框架,由于本人之前一直使用的Hibernate,对mybatis的用法实在欠缺,最近几天计划把mybatis学习一哈,特将学习笔记记 ...

  6. 关于从JSP页面插入数据到数据库中乱码问题的解决

    问题描述:最近我在写一个j2ee的留言板系统模块,遇到了一个非常让我头大的问题,当我从JSP页面输入数据后,通过hibernate中的业务逻辑类HQL语句把这个数据插入到本地的mysql数据库中,可是 ...

  7. Moon.Orm与其他Orm的技术对比

    有时候在思考大家为什么喜欢EF,为什么又出现这么多的Orm,为什么Nhiberate被人许多人接收又被许多人拒绝 最后发现结论:萝卜白菜各有所爱.适合自己的就是最好的. EF 微软团队支持(可谓强大的 ...

  8. 【ARL】Parallel Processing of Graphs

    Graph 本次学术前沿讲座由邵斌老师主讲,标题已经揭示了主题:Graph.1.5h的talk,听完自觉意犹未尽.本来以为是一节自己没接触过的图形学的talk,没想到讲的很多内容都跟自己学过的很多东西 ...

  9. C# DataGridView中指定的单元格不能编辑

    注意:DataGridView控件是从.NET Framework 2.0版本开始追加的. ReadOnly属性的使用 DataGridView内所有的单元格不能编辑 当DataGridView.Re ...

  10. MyBatis Mapper.xml文件中 $和#的区别

    MyBatis Mapper.xml文件中 $和#的区别   网上有很多,总之,简略的写一下,作为备忘.例子中假设参数名为 paramName,类型为 VARCHAR . 1.优先使用#{paramN ...