并发服务器一.docx

上传人:b****6 文档编号:3155128 上传时间:2022-11-18 格式:DOCX 页数:25 大小:1.99MB
下载 相关 举报
并发服务器一.docx_第1页
第1页 / 共25页
并发服务器一.docx_第2页
第2页 / 共25页
并发服务器一.docx_第3页
第3页 / 共25页
并发服务器一.docx_第4页
第4页 / 共25页
并发服务器一.docx_第5页
第5页 / 共25页
点击查看更多>>
下载资源
资源描述

并发服务器一.docx

《并发服务器一.docx》由会员分享,可在线阅读,更多相关《并发服务器一.docx(25页珍藏版)》请在冰豆网上搜索。

并发服务器一.docx

并发服务器一

四川大学计算机学院、软件学院

实验报告

课程名称

信息安全产品开发实践 

实验课时

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];

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 法语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1