并发服务器一.docx
- 文档编号:3155128
- 上传时间:2022-11-18
- 格式:DOCX
- 页数:25
- 大小:1.99MB
并发服务器一.docx
《并发服务器一.docx》由会员分享,可在线阅读,更多相关《并发服务器一.docx(25页珍藏版)》请在冰豆网上搜索。
并发服务器一
四川大学计算机学院、软件学院
实验报告
课程名称
信息安全产品开发实践
实验课时
5
实验项目
并发服务器
(一)
实验时间
2011年10月09号
实验目的
1)继续了解Linux下C语言程序开发的过程
2)掌握服务器分为哪几种模型
3)能在Linux环境实现TCP多进程并发服务器模型
4)了解什么是僵尸程序及相应的解决方法
实验环境
VMware5.0,RedHatLinux9.0
实验内容(算法、程序、步骤和方法)
试验题目1
∙自己编写程序实现远程控制系统中使用到函数popen功能;
试验题目2
∙修改远程控制服务器代码,使得服务器同时能够向多个用户提供服务。
在开始这次实验之前,我们先来了解一下现在常见的服务器模型:
现在的服务器一般分为两种模型:
(1)循环(重复)服务器模型:
每次只能处理一个客户的请求,但上一个客户的请求完成后,才能处理下一个客户的请求;
(2)并发服务器模型:
服务器在同一时刻可以响应多个客户的请求;
接着我们需要了解如何去实现这两类服务器模型,通常来说实现服务器程序不外乎利用UDP和TCP两种方式。
下面来看下具体的流程:
UDP:
(1):
UDP重复模型
UDP循环服务器的实现非常简单:
UDP服务器每次从套接字上读取一个客户端的请求,处理, 然后将结果返回给客户机.
socket(...);
bind(...);
while
(1)
{
recvfrom(...);
process(...);
sendto(...);
}
(2):
UDP并发服务器
人们把并发的概念用于UDP就得到了并发UDP服务器模型. 并发UDP服务器模型其实是简单的.和并发的TCP服务器模型一样是创建一个子进程来处理的 算法和并发的TCP模型一样.
除非服务器在处理客户端的请求所用的时间比较长以外,人们实际上很少用这种模型.
TCP:
(1):
TCP重复服务器模型
socket(...);
bind(...);
listen(...);
while
(1)
{
accept(...);
while
(1)
{
read(...);
process(...);
write(...);
}
close(...);
}
TCP服务器接受一个客户端的连接,然后处理,完成了这个客户的所有请求后,断开连接.
(2):
TCP多进程并发服务器模型
socket(...);
bind(...);
listen(...);
while
(1)
{
accept(...);
if(fork(..)==0)
{
Close(listenfd)
while
(1)
{
read(...);process(...);write(...);
}
close(...);exit(...);
}
close(...);
}
elseif(fork()>0)
{
close(accept);
continue;
}
}
接下来我们在来看一下在Linux下支持并发服务器模型的方式。
一般来说有下面的三种方式:
(1)多进程
(2)多线程
(3)I/O多路复用
在经过上面这么多得理论的分析之后,我们对服务器的类别及实现方法有了大致的了解。
回顾第四周做得实验,我们知道之前做得用TCP和UDP实现服务器端和客户端的方式都属于循环服务器模型,即服务器在一个阶段之内只能处理一个客户,并且只有在一个客户被处理完之后才能继续相应下一个客户的请求。
那门我们今天就要实现并发服务器模型。
进一步分析,我们得之,如果是用UDP实现的循环服务器,那么它同时也是并发服务器,即不需要任何修改,之前的循环UDP服务器就能实现UDP并发服务器的功能,因为UDP在服务器与客户端通信是不需要建立连接的。
所以我们今天的工作就是编程实现TCP并发服务器模型。
由于基本原理之前类似,所以我们只需要在原来的程序上做少量的修改,就可以实现TCP的并发服务器。
下面进入实验。
实验一:
实验步骤:
(1):
popen()函数的作用是用创建管道的方式启动一个进程。
在第四周的试验中我们通过这个函数完成了远程控制系统的编写。
今天我们就自己编写函数来代替popen()函数,达到同样的效果。
(2):
先来分析一下思路:
我们可以利用使用管道pipe(intf_des[2])函数(参数f_des[0]用于读取管道,f_des[1]用于向管道写入数据),通过管道实现父子进程间通讯。
(3)所以程序可以分为以下四个部分:
1.创建管道;
2.创建子进程;
3.在父进程中:
关闭f_des[1],使用wait操作与等待子进程,然后将管道中的数据读出打印显示;
4.在子进程:
关闭f_des[0],将管道f_des[1]与标准输出进行重定向(dup2(f_des[1],STDOUT_FILENO)),然后调用execvp()函数执行程序中接收到的命令;
(4)接下来我们就可以编写自己的程序了,打开虚拟机,利用VI编辑器将我们的程序命名为mypopen.c
(5)保存mypopen.c,使用命令gcc–omypopenmypopen.c–g命令编译程序。
(6)执行./mypopen,输入命令:
ls
(7)再次执行./mypopen,输入命令who
(8)执行命令./mypopen,输入命令:
pwd
(9)经过以上步骤的验证,说明我们自己编写的mypopen.c函数正确的实现了popen()的功能。
本函数与Linux中的popen()函数实现最大的不同是不需要用专门的pclose()函数来关闭文件指针,用普通的fclose()即可。
实验二:
实验步骤:
(1):
就像之前说得实现TCP并发服务器有三种方式,今天我们利用多进程的方式来实现这个目的。
在编写TCP的并发服务器之前,我们先来看下TCP多进程并发模型的流程图。
(2):
根据流程图我们就可以在Linux进行程序的编写了,打开虚拟机,在Linux下的VI编辑器中编写服务器端程序tcpserver.c
上述红色区域是代码修改的地方,而且在头文件需加入#include
(3)使用命令gcc–otcpservertcpserver.c–g编译;
(4):
编写客户端代码,客户端代码是不需要修改的,在vi下编辑tcpclient.c,保存,编译。
(5)打开一个终端,执行服务器端程序./tcpserver
(6)打开第二个终端,执行第一个客户端命令./tcpclient127.0.0.1
(7)打开第三个终端,执行第二个客户端命令./tcpclient127.0.0.1
(8)第一个客户端程序继续输入命令:
who
(9):
第二个客户端程序继续输入命令:
who
(接上)
实验内容(算法、程序、步骤和方法)
(10):
第一个客户端程序继续输入命令:
quit
(11):
第二个客户端程序继续输入命令:
quit
(12):
从上面的演示效果来看程序很好的实现了并发服务器的功能,即服务器在同一阶段能与多个客户进行通信。
附试验源代码:
mypopen.c
//mypopen.c
#include
#include
#include
#include
intmain(intargc,char**argv)
{
pid_tpid;
intf_des[2];
charcmd[1024];
printf("Pleaseinputyourcommand:
");
scanf("%s",&cmd);
if(-1==pipe(f_des))
{
perror("createpipeerror\n");
exit
(1);
}
if(pid=fork()<0)
{
perror("createforkerror\n");
exit
(1);
}
elseif(pid=fork()>0)
{
printf("Thisisinparentprocess\n");
close(f_des[1]);
wait();
charbuffer[1024];
intreadByte=read(f_des[0],buffer,sizeof(buffer));
buffer[readByte]='\0';
printf("Themessageis:
%s\n",buffer);
exit(0);
}
else
{
close(f_des[0]);
dup2(f_des[1],STDOUT_FILENO);
char*argv[]={cmd,NULL};
execvp(cmd,argv);
exit(0);
}
}
tcpserver.c
//tcpserver.c
#include
#include
#include
#include
#include
#include
#include
#definePORT8900
#defineBUFSIZE2048
intexecute(char*command,char*buf)
{
FILE*fp;
intcount;
charcommandbuf[2056];
if((NULL==command)||(NULL==buf))
{
perror("commandorbufisempty\n");
return-1;
}
count=0;
memset(commandbuf,0,2056);
strcat(commandbuf,"sh-c");
strcat(commandbuf,command);
fprintf(stderr,"thecommandis%s\n",commandbuf);
if(NULL==(fp=popen(commandbuf,"r")))
{
perror("createpipeerror\n");
return-1;
}
while((count<2047)&&(EOF!
=(buf[count++]=fgetc(fp))));
buf[count-1]='\0';
returncount;
}
intmain()
{
intsockfd;
//pid_tpid;
intconn_sock;
charsendbuf[BUFSIZE];
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 并发 服务器