目录

计算机网络-服务器模型

计算机网络-服务器模型

一.服务器模型

1.支持多客户端访问

//单循环服务器

socket

bind

listen

while(1)

{

accept

while(1)

{

recv/send

}

}

close

https://i-blog.csdnimg.cn/direct/470e3e0af6c144278a72703c81040151.png

注:该模式remvform为阻塞态,服务器将等待接收数据

2..支持多客户端同时访问 (并发能力)

socket

bind

listen

while(1)

{

connf = accept

pid_t pid = fork();

//出错处理

if (pid == 0)

{

while(1) //负责 与 客户端通信的

{

recv/send

}

}

}

close

https://i-blog.csdnimg.cn/direct/d185755507cf4b9a878517cac27f28e9.png

https://i-blog.csdnimg.cn/direct/01f1db96016246518be6d8bd3f2fa7bb.bmp

注:将管道设置成非阻塞一直读取

https://i-blog.csdnimg.cn/direct/f132b873ee8a4c6dad9eb303d08d9ddc.bmp

读端设置非阻塞

//线程

void *handle_client(void *arg)

{

while(1) //子线程中 负责 与 客户端通信的

{

recv/send

}

}

socket

bind

listen

while(1)

{

connf = accept

pthread_create();

//出错处理

}

close

二,三种服务器模型:

1.单循环服务器 2.并发服务器

进程

线程

1、简单循环服务器

http

web 服务器,apache–》cgi,php,perl,IIS–》asp,NGIX,Nlighty

while(1)

{

newfd = accept();

recv();

close(newfd);

}

特点:可以接入多个客户端的信息。

缺点:数据通信过程短,客户端只能一次有效。

实时性效果差。

2、fork循环服务器===>每次有链接则fork一个子进程为该

链接处理通信过程,父进程继续等待新链接。

while(1)

{

newfd  = accept();

pid = fork()

if(pid  == 0)

{

///接收数据

}

if(pid < 0)

{

perror(“fork”);

return -1;

}

waitpid()

}

特点:可以完成多个进程的实时交互,信息的完整性可以保证。

缺点:回收资源不方便,每次fork 占用系统资源多。

可能出现僵尸进程

多线程:

特点:

创建速度快,调度快

缺点:

线程共享进程资源,稳定性,安全性 较差

3.并发的服务器模型 —更高程度上的并发

IO模型

阻塞IO

非阻塞IO

1、阻塞IO

用的最多。

读阻塞。

写阻塞。

2、非阻塞IO

-1 errno EAGAIN  whild(1){read()break;}忙等待

contro

https://i-blog.csdnimg.cn/direct/a8b9f0b69281404daf2aaf304cd0fb8d.png

https://i-blog.csdnimg.cn/direct/b2d76782354a4e86ad58a74d02ed96c3.bmp

注:信号驱动IO

4.SELECT函数并发

#include <unistd.h>

#include <fcntl.h>

int fcntl(int fd, int cmd, … /* arg */ );

功能:修改指定文件的属性信息。

参数:fd 要调整的文件描述符

cmd 要调整的文件属性宏名称

… 可变长的属性值参数。

返回值:成功  不一定,看cmd

失败  -1;

int fcntl(int fd, int cmd, … /* arg */ );

//驱动:

//1.驱动程序 —- 驱使硬件工作起来的程序

让灯亮起来

//2.应用程序

应用程序

led_ctnl(led_fd,ON );

led_ctnl(led_fd,OFF );

led_ctnl(led_ctnl,STREAM); //流水灯

eg:修改文件的非阻塞属性:

int flag ;

flag  = fcntl(fd,F_GETFL,0);  ///获取fd文件的默认属性到flag变量中。

flag  = flag | O_NONBLOCK;    ///将变量的值调整并添加非阻塞属性

fcntl(fd,F_SETFL,flag);       ///将新属性flag设置到fd对应的文件生效。

以上代码执行后的阻塞IO将变成非阻塞方式。

https://i-blog.csdnimg.cn/direct/7dce2f34bec049c1a22613bf0ac4df96.png