信息安全实践第七次作业 并发服务器._第1页
信息安全实践第七次作业 并发服务器._第2页
信息安全实践第七次作业 并发服务器._第3页
信息安全实践第七次作业 并发服务器._第4页
信息安全实践第七次作业 并发服务器._第5页
已阅读5页,还剩8页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、四 川 大 学 计 算 机 学 院、软 件 学 院实 验 报 告 学号:姓名:专业:_软件工程_ 班级: 第 5 周 课程名称 信息安全产品开发实践 实验课时4实验项目并发服务器实验时间2013.10.18实验目的 1、修改远程控制服务器代码,使得服务器同时能够向多个用户提供服务。2、自己编写程序实现远程控制系统中使用到函数popen功能。实验环境 虚拟机 Red Hat Linux-VMware Workstation虚拟机 Ubuntu-VMware Workstation 实验内容(算法、程序、步骤和方法) 本次客户端代码和第4次实验的客户端代码一样这里就不多说了。 服务器代码主要是针对

2、第4次实验的服务器代码进行修改,主要修改内容为两个:1、 把原来的服务器改成并发的,这个比较简单,只要利用fork()函数就能完成子进程的建立,每接收到一个客户端的连接就创建一个子进程并把socket传递给一个叫work()的函数,然后由work()函数进行对客户端的回应。同时,这里还用了waitpid()函数,在防止僵尸进程的出现的同时又不会阻塞父进程的进行(当然还可以通过建立孙子进程然后杀死子进程的方式解决,这里就不多说了)。2、 第二部分比较难,主要体现在execlp的使用(为了如何给命令分段并分别传进参数而烦恼了很久),这里我们另建一个函数exec来完成原来popen()函数实现的功能

3、。我们先看一下服务器代码:(接上)实验内容(算法、程序、步骤和方法)#include#include#include#include#include#include#include#include#include#define PORT 8900#defineSIZE 2048/* 2K BUFFER */void exec (char* command,char* true_result)FILE * in;char c;char result2048;memset(result,0,2048);int fd2;int pid;if (pipe(fd)0)printf(create pipe

4、 failn);if (pid = fork()(recvnum = recv(connectd,recv_buf,sizeof(recv_buf),0)perror(recv errorn);close(connectd);continue;recv_bufrecvnum-1=0;/这里要注意-1,不然会保留换行符if (0=strcmp(recv_buf,quit)|(0=strcmp(recv_buf,QUIT)/结束对话,跳出内部循环,继续外部循环printf(overn);break;sscanf(recv_buf,%s %s,cmd,path);if (0=strcmp(cd,cm

5、d) |(0=strcmp(CD,cmd)chdir(path);continue;exec(recv_buf,send_buf);rvalue=-1;rvalue=send(connectd,send_buf,sizeof(send_buf),0);int main(int argc,char* argv)struct sockaddr_in server;struct sockaddr_in client;int len;int port;int listend;int connectd;int sendnum;int opt;char addr_p2048;/存储客户端地址的缓冲区int

6、 pid;port= PORT;opt = SO_REUSEADDR;if (-1=(listend=socket(AF_INET,SOCK_STREAM,0)/使用TCP创建监听用的套接字perror(create listen socket errorn);exit(1);setsockopt(listend,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt);#ifdef DEBUGprintf(the listen id is %dn,listend);#endifmemset(&server,0,sizeof(struct sockaddr_in);se

7、rver.sin_family = AF_INET;/IPv4协议server.sin_addr.s_addr = htonl(INADDR_ANY);/接收任意地址server.sin_port = htons(port);/设置端口号if (-1=bind(listend,(struct sockaddr *)&server,sizeof(struct sockaddr)/绑定perror(bind errorn);exit(1); if (-1=listen(listend,5) perror(listen errorn);exit(1); memset(&client,0,sizeof

8、(struct sockaddr_in);client.sin_family = AF_INET;/IPv4协议while(1)/外部死循环,用来重复连接客户端if (-1=(connectd=accept(listend,(struct sockaddr*)&client,&len)/创建新的套接字连接客户端perror(create connect socket errorn);continue;inet_ntop(AF_INET,&client.sin_addr,addr_p,sizeof(addr_p);/将客户端地址转为字符串printf(client IP is %s, port

9、is %dn,addr_p,ntohs(client.sin_port);pid = fork();if (pid 0)printf(fail to forkn);exit(1); else if (pid = 0)work(connectd);exit(0);if (waitpid(pid,NULL,WNOHANG) = -1)printf(fail to waitpidn); close(listend); return 0;代码有点长,就不一一讲解了,这里挑几个重点来讲:1、 exec函数调用了execlp函数,整个命令字符串(不用分段)作为函数输入:execlp(sh,sh,-c,co

10、mmand,NULL)。这里通过调用sh执行脚本来执行命令,在这里第二个参数也可以写成”sh -c”(即execlp(sh,sh -c,-c,command,NULL),但是第三个参数必须写成”-c”(即不可execlp(sh,sh -c,command,NULL)),不然运行出问题。2、 由于这里另外用了个execexec (char* command,char* true_result)函数对命令和结果进行地址传递,但是这里必须注意的是不可以直接把管道内的内容输出到true_result,这样会出现问题,由于true_result是字符串指针,所以默认它的大小只有4个字节,如果理所当然地把

11、管道内容输到true_result中,true_result也只会收到前4个字节,返回给客户端的也只有原本应该要传输的字符串的头4个字节,这里有两个解决方案:(1) 不能用read(fd0,true_result,sizeof(true_result),因为sizeof(true_result)为4,这里应该用read(fd0,true_result,2048)。(2) 另一种就是比较规范的写法了,在exec函数中另外声明char result2048,把管道的内容输到result中,在函数的最后在把result的内容复制到true_result中。当然直接不用exe函数直接把代码写在work函数中也行。3、 这里还有一个细节,如果用了2中的(2)方法

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论