实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx

上传人:b****6 文档编号:10188974 上传时间:2023-02-09 格式:DOCX 页数:15 大小:113.51KB
下载 相关 举报
实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx_第1页
第1页 / 共15页
实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx_第2页
第2页 / 共15页
实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx_第3页
第3页 / 共15页
实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx_第4页
第4页 / 共15页
实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx

《实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx》由会员分享,可在线阅读,更多相关《实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx(15页珍藏版)》请在冰豆网上搜索。

实验一基于TCP套接字的文件传输客户服务器程序设计实验报告.docx

实验一基于TCP套接字的文件传输客户服务器程序设计实验报告

2011年秋季学期《计算机网络II》实验报告

 

考核科目:

计算机网络II

学生所在院(系):

计算机科学与技术学院

学生所在学科:

姓名:

学号:

实验时间:

2011年11月29日

 

一、问题描述

1.实验名称:

基于TCP套接字的文件传输客户服务器程序设计

2.实验目的:

掌握基于TCP套接口的网络程序设计。

掌握大规模文件传输的基本方法。

3.实验要求:

服务器程序分别实现迭代服务器,并发服务器,使用单进程和select的TCP服务器。

服务器在客户提出请求后向客户发送一个不小于1M大小的文件。

二、概要设计

1.客户程序概要设计。

创建TCP套接口;

指定服务器IP地址和端口;

建立与服务器的连接;

向服务器发送请求传送文件的请求“hello”;

接受服务传输过来的数据;

终止程序。

2.迭代服务器概要设计。

创建TCP套接口;

捆绑服务器众所周知端口到套接口;

把套接口变成监听套接口;

接受客户连接;

读取客户的请求,发送应答;

终止连接并等待下一个客户连接。

3.并发服务器概要设计。

创建TCP套接口;

捆绑服务器众所周知端口到套接口;

把套接口变成监听套接口;

接受客户连接;

调用fork()派生子进程处理连接,父进程等待新的连接请求并处理结束的子进程;

子进程读取客户的请求,发送应答,数据传输结束后终止连接并退出。

4.使用单进程和select的TCP服务器概要设计。

创建TCP套接口;

捆绑服务器众所周知端口到套接口;

把套接口变成监听套接口;

调用select初始化数据结构;

阻塞于select;

若监听套接字变为可读,accept新的连接;

检查现有连接,若连接可读则读取客户请求,发送应答,数据传输结束后关闭当前连接并更新数据结构。

三、详细设计

1.客户程序详细设计。

a)主要数据结构设计

ipv4套接字地址结构

structin_addr{

in_addr_ts_addr;

};

structsockaddr_in{

uint8_tsin_len;

sa_family_tsin_family;

in_port_tsin_port;

structin_addrsin_addr;

charsin_zero[8];

};

字符数组

charbuf[MAXSIZE];

b)主要函数功能

socket(),connect(),writen(),readn(),close()

intsocket(intdomain,inttype,intprotocol);

指定期望的通信协议类型。

返回值:

成功则为非负描述符,出错则为-1。

intconnect(intsockfd,conststructsockaddr*addr,socklen_taddrlen);

tcp客户用connect函数来建立与tcp服务器的连接。

ssize_treadn(intfd,void*vptr,size_tn);

从一个描述字读n个字节到vptr所指的缓冲区。

ssize_twriten(intfd,constvoid*vptr,size_tn);

从vptr所指的缓冲区中写n个字节到一个描述字。

intclose(intfd);

关闭描述字。

2.迭代服务器详细设计。

a)主要数据结构设计

ipv4套接字地址结构(略)

字符数组

charbuf[MAXSIZE];

b)主要函数功能

socket(),bind(),listen(),accept(),writen(),readn(),close()

intbind(intsockfd,conststructsockaddr*addr,socklen_taddrlen);

bind函数把一个本地协议地址赋予一个套接字。

对于网际网协议,协议地址就是32位的ipv4地址或者128位的ipv6地址与16位的tcp或udp端口号的组合。

如果一个tcp客户或者服务器未曾调用bind捆绑一个端口,当调用connect或listen时,内核就要为相应的套接字选择一个临时的端口。

intlisten(intsockfd,intbacklog);

listen函数把一个未连接的套接字转换成一个被动的套接字,指示内核接受指向该套接字的连接请求。

intaccept(intsockfd,structsockaddr*addr,socklen_t*addrlen);

accept函数由tcp服务器调用,用于从已完成连接的队列队头返回下一个已完成连接。

如果已完成连接的队列为空,那么进程被投入睡眠。

3.并发服务器详细设计。

a)主要数据结构设计

ipv4套接字地址结构(略)

字符数组

charbuf[MAXSIZE];

b)主要函数功能

socket(),bind(),listen(),accept(),witen(),readn(),signal(),close()

typedefvoidSigfunc(int);

Sigfunc*signal(intsigno,Sigfunc*func);

调用函数func处理信号signo。

4.使用单进程和select的TCP服务器详细设计。

a)主要数据结构设计

ipv4套接字地址结构(略)

字符数组

charbuf[MAXSIZE];

b)主要函数功能

socket(),bind(),listen(),accept(),writen(),readn(),select(),

FD_SET(),FD_ISSET(),close()

intselect(intnfds,fd_set*readfds,fd_set*writefds,

fd_set*exceptfds,structtimeval*timeout);

voidFD_CLR(intfd,fd_set*set);

intFD_ISSET(intfd,fd_set*set);

voidFD_SET(intfd,fd_set*set);

voidFD_ZERO(fd_set*set);

select()函数允许进程指示内核等待多个事件中的任意一个发生,并仅在一个或者多个事件发生或经过某指定的时间后才唤醒进程。

FD_CLR()清除描述字fd相应位;

FD_ISSET()测试描述字fd相应位;

FD_SET()在描述字集合中为fd设置相应位;

FD_ZERO()初始化描述字集合。

四、实验结果

迭代服务器

并发服务器

使用单进程和select的TCP服务器

五、心得体会

未知的事情总显的神秘,以前一直认为在网络中传输数据是很复杂的事情。

对“套接字”也只是有个泛泛的概念,知道网络编程要也能够到这个。

接触以后,感觉最基本的套接字编程还是挺简单的。

但是考虑到各种有可能发生的情况之后,程序就变得复杂了。

六、附录:

(数据结构、核心代码)

/*myfunc.h*/

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#defineSERV_PORT9996

#defineMAXSIZE1024

typedefvoidSigfunc(int);

ssize_treadn(intfd,void*vptr,size_tn)

{

ssize_tnleft;

ssize_tnread;

char*ptr;

ptr=vptr;

nleft=n;

while(nleft>0){

if((nread=read(fd,ptr,nleft))<0){

if(errno==EINTR)

nread=0;

else

return(-1);

}elseif(nread==0)

break;

nleft-=nread;

ptr+=nread;

}

return(n-nleft);

}

ssize_twriten(intfd,constvoid*vptr,size_tn)

{

size_tnleft;

ssize_tnwritten;

constchar*ptr;

ptr=vptr;

nleft=n;

while(nleft>0){

if((nwritten=write(fd,ptr,nleft))<=0){

if(errno==EINTR)

nwritten=0;

else

return(-1);

}

nleft-=nwritten;

ptr+=nwritten;

}

return(n);

}

voidsig_chid(intsigno)

{

pid_tpid;

intstat;

while((pid=waitpid(-1,&stat,WNOHANG))>0){

printf("child%dterminated\n",pid);fflush(stdout);}

return;

}

Sigfunc*signal(intsigno,Sigfunc*func)

{

structsigactionact,oact;

act.sa_handler=func;

sigemptyset(&act.sa_mask);

act.sa_flags=0;

if(signo==SIGALRM){

#ifdefSA_INTERRUPT

act.sa_flags|=SA_INTERRUPT;

#endif

}else{

#ifdefSA_RESTART

act.sa_flags|=SA_RESTART;

#endif

}

if(sigaction(signo,&act,&oact)<0)

return(SIG_ERR);

return(oact.sa_handler);

}

/*client.c*/

#include"myfunc.h"

intmain(intargc,char**argv)

{

intsockfd;

structsockaddr_inservaddr;

if(argc!

=2)

printf("usage:

tcpcli");

if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)

printf("socketerror!

");

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family=AF_INET;

servaddr.sin_port=htons(SERV_PORT);

servaddr.sin_addr.s_addr=inet_addr(argv[1]);

if(connect(sockfd,(structsockaddr*)&servaddr,sizeof(servaddr))<0)

{

printf("linkerror!

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

return0;

}

charasd[5]="hello";

writen(sockfd,asd,5);

charbuf[MAXSIZE]={};

intd=0;

intfile_len=0;

intfds=open("file_in_client.txt",O_CREAT|O_RDWR|O_TRUNC,0666);

while((d=readn(sockfd,buf,MAXSIZE)))

file_len+=writen(fds,buf,d);

printf("file_len:

%d\n",file_len);

printf("Thefilehasbeenreceived!

\n");

return0;

}

/*server_1.c*/

#include"myfunc.h"

intmain(intargc,char**argv)

{

intn,m,b,listenfd,connfd;

structsockaddr_inservaddr;

if(n=(listenfd=socket(AF_INET,SOCK_STREAM,0))<0)

printf("listenerror");

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family=AF_INET;

servaddr.sin_addr.s_addr=htonl(INADDR_ANY);

servaddr.sin_port=htons(9996);

if(m=(bind(listenfd,(structsockaddr*)&servaddr,sizeof(servaddr)))<0)

printf("binderror,%s",strerror(errno));

if((b=listen(listenfd,3))<0)

printf("blistenerror");

structsockaddr_inclientAdd;

for(;;)

{

socklen_tlen;

len=sizeof(clientAdd);

charbuf[MAXSIZE];

connfd=accept(listenfd,(structsockaddr*)&clientAdd,&len);

charqwe[5];

readn(connfd,qwe,5);

intfid=open("file_in_server.txt",O_RDWR,0666);

ints=0;

intlen1=0;

while(s=readn(fid,buf,MAXSIZE))

len1=writen(connfd,buf,s);

printf("seroneThefilehasbeensenttotheclient!

\n");

close(connfd);

}

}

/*server_2.c*/

#include"myfunc.h"

intmain(intargc,char**argv)

{

pid_tpid;

intn,m,b,listenfd,connfd;

structsockaddr_inservaddr;

voidsig_chid(int);

if(n=(listenfd=socket(AF_INET,SOCK_STREAM,0))<0)

printf("listenerror");

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family=AF_INET;

servaddr.sin_addr.s_addr=htonl(INADDR_ANY);

servaddr.sin_port=htons(SERV_PORT);

if(m=(bind(listenfd,(structsockaddr*)&servaddr,sizeof(servaddr)))<0)

printf("binderror,%s",strerror(errno));

if((b=listen(listenfd,3))<0)

printf("listenerror");

signal(SIGCHLD,sig_chid);

structsockaddr_inclientAdd;

for(;;)

{

socklen_tlen;

len=sizeof(clientAdd);

charbuf[MAXSIZE];

ints=0;

if((connfd=accept(listenfd,(structsockaddr*)&clientAdd,&len))<0){

if(errno==EINTR)

continue;

else

printf("accepterror\n");

}

if((pid=fork())==0)

{

close(listenfd);

charqwe[5];

readn(connfd,qwe,5);

intfid=open("file_in_server.txt",O_RDWR,0666);

intlen1=0;

while(s=readn(fid,buf,MAXSIZE))

len1=writen(connfd,buf,s);

printf("sertwoThefilehasbeensenttotheclient!

\n");

close(connfd);

exit(0);

}

close(connfd);

}

}

/*server_3.c*/

#include"myfunc.h"

intmain(intargc,char**argv)

{

inti,maxfd,maxi,listenfd,connfd,sockfd;

intnready,client[FD_SETSIZE];

fd_setrset;

charbuf[MAXSIZE];

socklen_tclilen;

structsockaddr_incliaddr,servaddr;

listenfd=socket(AF_INET,SOCK_STREAM,0);

bzero(&servaddr,sizeof(servaddr));

servaddr.sin_family=AF_INET;

servaddr.sin_addr.s_addr=htonl(INADDR_ANY);

servaddr.sin_port=htons(SERV_PORT);

bind(listenfd,(structsockaddr*)&servaddr,sizeof(servaddr));

listen(listenfd,3);

maxfd=listenfd;

maxi=-1;

for(i=0;i

client[i]=-1;

FD_ZERO(&rset);

for(;;){

FD_SET(listenfd,&rset);

nready=select(maxfd+1,&rset,NULL,NULL,NULL);

if(FD_ISSET(listenfd,&rset)==1){

clilen=sizeof(cliaddr);

connfd=accept(listenfd,(structsockaddr*)&cliaddr,&clilen);

for(i=0;i

if(client[i]<0){

client[i]=connfd;

break;

}

if(i==FD_SETSIZE){

printf("toomanyclients");

fflush(stdout);

}

FD_SET(connfd,&rset);

if(connfd>maxfd)

maxfd=connfd;

if(i>maxi)

maxi=i;

if(--nready<=0)

continue;

}

for(i=0;i<=maxi;i++){

if((sockfd=client[i])<0)

continue;

if(FD_ISSET(sockfd,&rset)){

charqwe[10];

readn(connfd,qwe,5);

intfid=open("file_in_server.txt",O_RDWR,0666);

ints=0;

intlen1=0;

while(s=readn(fid,buf,MAXSIZE))

len1=writen(sockfd,buf,s);

printf("Thefilehasbeensenttotheclient!

\n");

close(sockfd);

FD_CLR(sockfd,&rset);

client[i]=-1;

}

}

}

return0;

}

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

当前位置:首页 > 解决方案 > 解决方案

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

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