信息安全实践第八次作业 并发服务器II——多线程.docx

上传人:wj 文档编号:654372 上传时间:2023-04-29 格式:DOCX 页数:21 大小:223.11KB
下载 相关 举报
信息安全实践第八次作业 并发服务器II——多线程.docx_第1页
第1页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第2页
第2页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第3页
第3页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第4页
第4页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第5页
第5页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第6页
第6页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第7页
第7页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第8页
第8页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第9页
第9页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第10页
第10页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第11页
第11页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第12页
第12页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第13页
第13页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第14页
第14页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第15页
第15页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第16页
第16页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第17页
第17页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第18页
第18页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第19页
第19页 / 共21页
信息安全实践第八次作业 并发服务器II——多线程.docx_第20页
第20页 / 共21页
亲,该文档总共21页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

信息安全实践第八次作业 并发服务器II——多线程.docx

《信息安全实践第八次作业 并发服务器II——多线程.docx》由会员分享,可在线阅读,更多相关《信息安全实践第八次作业 并发服务器II——多线程.docx(21页珍藏版)》请在冰点文库上搜索。

信息安全实践第八次作业 并发服务器II——多线程.docx

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

实 验 报 告

学号:

姓名:

专业:

软件工程

班级:

第 7 周

课程名称

信息安全产品开发实践

实验课时

4

实验项目

并发服务器II——多线程

实验时间

2013.10.25

实验目的

1、修改远程控制程序服务器程序,将其从循环模式或多进程模式修改为多线程模式

2、实现一个多线程端口扫描程序

实验环境

虚拟机RedHatLinux-VMwareWorkstation

虚拟机Ubuntu-VMwareWorkstation

实验内容

(算法、程序、步骤和方法)

第一个比较简单,我直接把上次实验的多进程远程控制服务器改成多线程远程控制服务器了。

这里需要注意的是为了防止僵尸线程这里在建立线程时设置了属性,使子线程成为分离线程。

#include#include#include#include#include#include#include#include#include#include

#definePORT8900

#define SIZE2048 /*2KBUFFER*/

void exec(char*command,char*true_result)

{

FILE*in;charc;

charresult[2048];

memset(result,0,2048);

intfd[2];intpid;

if(pipe(fd)<0)

printf("createpipefail\n");

if((pid=fork())<0)printf("forkpipefail\n");

elseif(pid==0)

{

close(fd[0]);

dup2(fd[1],STDOUT_FILENO);

execlp("sh","sh","-c",command,NULL);

}

close(fd[1]);

read(fd[0],result,sizeof(result));

strcpy(true_result,result);

}

void*work(void*connectd){

intrecvnum;intrvalue;

charcmd[10]; /*these

twovarusedtodealwithcdcommand*/

charpath[2048];

charrecv_buf[2048];charsend_buf[2048];

while

(1)

{

memset(send_buf,0,2048);memset(recv_buf,0,2048);

if(0>(recvnum=recv((int)connectd,recv_buf,sizeof(recv_buf),0)))

{

perror("recverror\n");close((int)connectd);continue;

}

recv_buf[recvnum-1]='\0'; //这里要注意-1,不然会保留换行符

if(0==strcmp(recv_buf,"quit")||(0==strcmp(recv_buf,"QUIT"))

{//结束对话,跳出内部循环,继续外部循环printf("over\n");

break;

}

sscanf(recv_buf,"%s%s",cmd,path);

if((0==strcmp("cd",cmd))||(0==strcmp("CD",cmd)))

{

chdir(path);continue;

}

exec(recv_buf,send_buf);

rvalue=-1;rvalue=send((int)connectd,send_buf,sizeof(send_buf),0

);

}

}

intmain(intargc,char**argv)

{

structsockaddr_inserver;structsockaddr_inclient;intlen;

intport;intlistend;intsendnum;intopt;

charaddr_p[2048]; //存储客户端地址的缓冲区

intpid;

port=PORT;

opt=SO_REUSEADDR;

if(-1==(listend=socket(AF_INET,SOCK_STREAM,0)))//使

用TCP创建监听用的套接字

{

perror("createlistensocketerror\n");exit

(1);

}

setsockopt(listend,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));

#ifdefDEBUG

printf("thelistenidis%d\n",listend);#endif

memset(&server,0,sizeof(structsockaddr_in));server.sin_family=AF_INET; //IPv4协议

server.sin_addr.s_addr=htonl(INADDR_ANY); //接收任意地址

server.sin_port=htons(port);//设置端口号

if(-1==bind(listend,(structsockaddr

*)&server,sizeof(structsockaddr)))

{ //绑定

perror("binderror\n");

exit

(1);

}

if(-1==listen(listend,5))

{

perror("listenerror\n");exit

(1);

}

memset(&client,0,sizeof(structsockaddr_in));client.sin_family=AF_INET; //IPv4协议

while

(1)

{//外部死循环,用来重复连接客户端

memset(&client,0,sizeof(structsockaddr_in));

intconnectd;//不确定是否一定要在循环以内

if(-1==(connectd=accept(listend,(structsockaddr*)&client,&len)))

{//创建新的套接字连接客户端

perror("createconnectsocketerror\n");continue;

}

inet_ntop(AF_INET,&client.sin_addr,addr_p,sizeof(addr

_p)); //将客户端地址转为字符串

printf("clientIPis%s,portis

%d\n",addr_p,ntohs(client.sin_port));

interr;pthread_ttid;

pthread_attr_tattr;

err=pthread_attr_init(&attr);if(err!

=0)

{

printf("can'tinitattr%s\n",strerror(err));exit

(1);

}

err=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED

);

if(err!

=0)

{

printf("can'tsetattr%s\n",strerror(err));exit

(1);

}

err=pthread_create(&tid,&attr,work,(void*)connectd);

if(err!

=0)

{

printf("can'tcreatethread

%s\n",strerror(err));

exit

(1);

}

}

close(listend);return0;

}

(接上)实验内容

(算法、程序、步骤和方法)

第二个实验是在之前那个端口扫描器的基础上修改的,有关建立线程的代码是在老师PPT上写的代码的基础上改的,如

port_segment中的dest原本是int,这里改成了直接用struct

sockaddr_in保存IP。

建立的线程比较多,依然使用了初始化属性来防止僵尸线程。

#include#include#include#include#include#include#include#include#include

#defineSEG_LEN655//一个线程扫描的端口数#defineTHREAD_NUM100//每个IP扫描建立的线程数#defineMAX_PORT65535//最大端口号

structport_seg

{

structsockaddr_inserver;unsignedmin_port;unsignedmax_port;

};

typedefstructport_segport_segment;

void*scan(void*arg){

port_segment*seg=(port_segment*)arg;intret;

intport=seg->min_port; //port为实际端口号

while(port<=seg->max_port) //把输入范围以内的所有都连接一次

{

seg->server.sin_port=htons(port); //每循环一次就设置一次端口号

intsockfd; //每次循环都重新建立套接字if(-

1==(sockfd=socket(AF_INET,SOCK_STREAM,0)))

{

perror("cannotcreatesocket\n");

exit

(1);

}

if(-1<(ret=connect(sockfd,(structsockaddr*)&seg->server,sizeof(structsockaddr))))

{

charaddr_p[2048];inet_ntop(AF_INET,&seg-

>server.sin_addr,addr_p,sizeof(addr_p));

printf("%s",addr_p);

printf("%d",port);

if(getservbyport(htons(port),"tcp")==

NULL)

printf("unknown\n");//服务为空的话就输

出unknown

else

printf("%s\n",getservbyport(htons(port),"tcp")-

>s_name);

}

close(sockfd);

port++; //端口号是递增的

}

//pthread_exit((void*)1);returnNULL;

}

intmain(intargc,char**argv)

{

intlen;

/*

f_port=atoi(argv[2]);//第一个端口号l_port=atoi(argv[3]);//最后一个端口号

*/

intdest_num=argc-1;//要扫描的IP数目

pthread_t*thread;

thread=(pthread_t*)malloc(THREAD_NUM*

sizeof(pthread_t));

intj=1;printf("%d\n",dest_num);

while(j<=dest_num){//外循环,一次针对一个IP

inti=0;

while(i

一个端口

port_segmentport;

memset(&port.server,0,sizeof(struct

sockaddr_in));

port.server.sin_family=AF_INET;port.server.sin_addr.s_addr=

inet_addr(argv[j]);

port.min_port=i*SEG_LEN+1;

/*thelastsegment*/

if(i==(THREAD_NUM-1))

port.max_port=MAX_PORT;

else

port.max_port=port.min_port+

SEG_LEN-1;

pthread_attr_tattr;

interr;

err=pthread_attr_init(&attr);if(err!

=0)

{

printf("can'tinitattr

%s\n",strerror(err));

exit

(1);

}

err=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED

);

if(err!

=0)

{

printf("can'tsetattr

%s\n",strerror(err));

exit

(1);

}

if(pthread_create(&thread[i],&attr,scan,(void*)&port)!

=0)

{

perror("pthread_createfailed\n");free(thread);

exit(-2);

}

++i;

}j++;

//free(thread);

}

//return0;

}

数据记录和计算

结 论

(结果)

通过

小 结

虽说这次实验使用了多线程,但连互斥量和读写锁都没用上,所以感觉自己有必要另外去写一些和同步线程有关的程序来熟悉多线程同步,同

时也要学习用gdb调试线程。

指导老师评 议

成绩评定:

指导教师签名:

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

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2