网络编程第2次上机.docx
- 文档编号:29900487
- 上传时间:2023-08-03
- 格式:DOCX
- 页数:13
- 大小:85.78KB
网络编程第2次上机.docx
《网络编程第2次上机.docx》由会员分享,可在线阅读,更多相关《网络编程第2次上机.docx(13页珍藏版)》请在冰豆网上搜索。
网络编程第2次上机
《网络编程技术》实验报告
得分:
班级
姓名
学号
实验名称
并发服务器编程---多线程服务器
实验室号
6302
实验目的
1.掌握多线程服务器的编写模板。
2.掌握多线程程序的编写方法。
实验要求
实验内容
1.认真阅读和掌握本实验的相关知识点。
2.上机编写并运行本程序。
3.保存程序的运行结果,并结合程序进行分析。
实验内容
采用多线程并发服务器技术,服务器可以同时接受多个客户的请求。
具体要求如下:
客户端:
1.根据客户输入的服务器IP地址和客户端本地端口号,向服务器发起建立连接的请求。
注意使用指定的客户端本地端口号与服务器连接。
2.接收从服务器端发送回来的文件内容,并保存。
保存前提示用户输入文件名。
服务器端:
1.接收并显示与之连接的客户端的IP地址与端口号。
2.若用户发起连接时使用的端口号是奇数,则传输文件A,否则传输文件B.AB具体文件具体文件名可自由指定。
3.使用多线程实现。
服务器端较高要求的可选部分内容:
若同时有多个使用奇数端口号或偶数端口号的客户端发起通信,要能将正确的文件内容发送给客户端。
实验步骤或源代码
服务器端代码:
<拷贝后直接运行>
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#definePORT1234
#defineBACKLOG5
#defineREADF100
voidprocess_cli(intconnfd,structsockaddr_inclient);
void*function(void*arg);
structARG{
intconnfd;
structsockaddr_inclient;
};
main()
{
intlistenfd,connfd;
pthread_ttid;
structARG*arg;
structsockaddr_inserver;
structsockaddr_inclient;
socklen_tlen;
if((listenfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
perror("Ceatingsocketfailed.");
exit
(1);
}
intopt=SO_REUSEADDR;
setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
bzero(&server,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(PORT);
server.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(listenfd,(structsockaddr*)&server,sizeof(server))==-1)
{
perror("Bind()error");
exit
(1);
}
if(listen(listenfd,BACKLOG)==-1)
{
perror("listen()error.\n");
exit
(1);
}
len=sizeof(client);
while
(1)
{
if((connfd=accept(listenfd,(structsockaddr*)&client,&len))==-1)//得到监听到的连接,此步转换达到连接
{
perror("accept()error.\n");
exit
(1);
}
arg=(structARG*)malloc(sizeof(structARG));
arg->connfd=connfd;
memcpy((void*)&arg->client,&client,sizeof(client));//分配空间给arg,然后把已连接描述符和客户信息付给arg
if(pthread_create(&tid,NULL,function,(void*)arg))//产生新线程,调用function函数,关键是释放arg的内容
{
perror("pthread_creat()error.");
exit
(1);
}
}
close(listenfd);
}
voidprocess_cli(intconnfd,structsockaddr_inclient)
{
intfd_file=-1;
intport_number;
intflag_access;
ssize_tsize=-1;
//charrecvbuf[MAXDATASIZE],sendbuf[MAXDATASIZE],sendnote[MAXDATASIZE];
charbuf[READF];
charA_filename[]="Aserverfile";
charB_filename[]="Bserverfile";//定义文件名
port_number=htons(client.sin_port);//这里关键是转换
printf("Yougotaconnectionfrom%s:
%d.\n",inet_ntoa(client.sin_addr),port_number);
//对连接端口进行判断
if((port_number)%2==0)
{
flag_access=1;
//send(connfd,"Youconnecttheserver--oushu.\n",29,0);//告知客户端成功连接
fd_file=open(B_filename,O_RDONLY);//打开文件
if(-1==fd_file)
{
printf("Openfile%sfailure,fd:
%d\n",B_filename,fd_file);//文件已经存在
}else
{
printf("Openfile%ssuccess,fd:
%d\n",B_filename,fd_file);//文件不存在,创建新文件
}
memset(buf,0,READF);
while
(1)
{
size=read(fd_file,buf,READF);
//printf("size%d",size);
if(-1==size){//读取出错处理
close(fd_file);//关闭文件
printf("readfileerroroccurs\n");
return0;//返回
}elseif(size>0)
{//读取成功
send(connfd,buf,size,0);
//printf("send<%d>bytes:
\n",total);//获得size的字节个数
}
else
{
close(connfd);
printf("sendover\n");
break;
}
}
//发送文件
printf("fileB,%d",flag_access);
}
else
{
flag_access=2;
//send(connfd,"Youconnecttheserver--jishu.\n",29,0);//告知客户端成功连接
fd_file=open(A_filename,O_RDONLY);//打开文件
if(-1==fd_file)
{
printf("Openfile%sfailure,fd:
%d\n",A_filename,fd_file);//文件已经存在
}else
{
printf("Openfile%ssuccess,fd:
%d\n",A_filename,fd_file);//文件不存在,创建新文件
}
memset(buf,0,READF);
while
(1)
{
size=read(fd_file,buf,READF);//每次读取100个字节
if(-1==size)
{//读取出错处理
close(fd_file);//关闭文件
printf("readfileerroroccurs\n");
return0;//返回
}elseif(size>0)
{//读取成功
send(connfd,buf,size,0);
//printf("send<%d>bytes:
\n",total);//获得size的字节个数
}
else
{
close(connfd);
printf("sendover\n");
break;
}
}
//发送文件
printf("fileA,%d",flag_access);
}
//对端口判断结束
close(connfd);
}
//实现调用process_cli()函数,把文件套接字给这个线程去处理
void*function(void*arg)
{
structARG*info;
info=(structARG*)arg;
printf("Theserverbeginning....\n");
process_cli(info->connfd,info->client);
printf("\nceshiceshiceshi\n");
free(arg);//释放分配给该线程的arg空间
pthread_exit(NULL);
exit
(1);
}
客户端代码:
<拷贝后直接运行>
#include
#include
#include
#include
#include
#include
#include
#include
#include
#definePORT1234
#defineFilename_Length100
#defineMSD100
#defineMAXDATASIZE100
voidprocess(intsockfd,intfd_file);
char*getMessage(char*sendline,intlen,FILE*fp);
voidspecify_port(intlocalport);
intmain(intargc,char*argv[])
{
intsockfd;
intlocal_portnumber=11111;//初始化本地端口号
intfd_file=-1;
charfilename[Filename_Length]="ooo";//默认文件名
structhostent*he;
structsockaddr_inserver;
structsockaddr_inclient;//为指定端口所用
//client.sin_port=46261;//指定端口
if(argc!
=2)
{
printf("Usage:
%s
exit
(1);
}
if((he=gethostbyname(argv[1]))==NULL)
{
printf("gethostbyname()error\n");
exit
(1);
}
if((sockfd=socket(AF_INET,SOCK_STREAM,0))==-1)
{
printf("socket()error\n");
exit
(1);
}
bzero(&server,sizeof(server));
server.sin_family=AF_INET;
server.sin_port=htons(PORT);
server.sin_addr=*((structin_addr*)he->h_addr);
printf("Pleaseinputthespecificallocalport:
:
:
:
:
:
");
scanf("%d",&local_portnumber);
printf("Connectedtoserver,andpleaseinputthefilename:
:
:
:
:
:
");
scanf("%s",&filename);
fd_file=open(filename,O_RDWR|O_CREAT|O_APPEND,00200);//以不存在则创建的原则
//指定文件名
printf("%s",filename);
client.sin_family=AF_INET;
client.sin_port=htons(local_portnumber);//指定客户机的端口
client.sin_addr.s_addr=htonl(INADDR_ANY);
if(bind(sockfd,(structsockaddr*)&client,sizeof(client))==-1)
{
perror("Bind()error");
exit
(1);
}
//指定结束
if(connect(sockfd,(structsockaddr*)&server,sizeof(server))==-1)
{
printf("connect()error\n");
exit
(1);
}
process(sockfd,fd_file);
close(sockfd);
}
voidprocess(intsockfd,intfd_file)
{
//charnoteline[MAXDATASIZE];
ssize_tsize,sss;
inttotal=0;
charbuf_re[MSD];
while
(1)//发送文件
{
size=recv(sockfd,buf_re,MSD,0);
sss=write(fd_file,buf_re,size);//将数据写入到文件receive.txt
total=total+size;
printf("Areadyreceived-----%d\n",total);
if(size<=0)
{
printf("%d\n",size);
break;
printf("Thefileisover");
printf("\n");
}
}
}
实验结论、心得体会
在进行多线程编程时,验证并发服务器的并发性,关键是是模拟并发访问,可以通过sleep()函数设定不同的访问时间,同时,保证在最大线程执行的时间内。
客户端可执行文件放在不同的文件夹内。
如图:
运行服务器端:
运行在本目录下运行客户端程序:
在./yy目录下运行客户端程序:
文件展示:
[在本录下]
[在./yy目录下]
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 网络 编程 上机