1、计算机网络课程设计报告题目:文件传输协议的设计与实现目录1.课程设计目的和要求2.背景知识3.课程设计分析4.程序清单5.运行结果6.总结1. 课程设计目的和要求文件传输是各种计算机的网络的基本功能,文件传送协议是一种最基本的应用层协议。它是按照客户或服务器模式进行的工作,提供交式的访问。是INTERNRT使用最广泛的协议之一。以及深入了解计算机网络是建立在TCP/IP网络体系结构上。用 socket 编程接口编写俩个程序,分别为客户程序和服务器程序1 掌握TCP/IP 网络应用程序基本的设计方法;2 用socket 编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(ser
2、ver.c);3 撰写课程设计说明书。装订后的课程设计说明书不少于10面(含封面、任务书、目录、正文、参考文献、成绩评定表、封底)。2. 背景知识第一个FTP的RFC由A.K.Bhushan 在1971年提出,同时由MIT与Harvard实验实现,RFC 172提供了主机间文件传输的一个用户级协议。长期发展过程由于底层协议从NCP改变为TCP,RFC765定义了采用TCP的FCP. FTP协议在今天已经发展成熟,应用也越来越广很多开发的比较成熟的FTP客户端软件已经得到了广泛的应用.3. 课程设计分析 Server端 Client端创建ServerSocket对象,在某端口提供监听服务Clie
3、nt端 等待来自Client端的服务请求 接受Client端的请求,用返回的 创建Socket对象,向Server Socket建立连接 的监听端口请求 通过向Socket中读写数据来 通过向新的Socket中读写数与Client端通信 据来与Server端通信关闭Socket,结束与Server端的通信 关闭Socket,结束与当前 Client的通信,等待其他请求关闭ServerSocket对象,结束监听服务4.程序清单:1. 服务器源代码:#include #include #include using namespace std;#pragma comment(lib, wsock32
4、.lib)#define PORT 4523char buf_send1024;char buf_rec1024;SOCKET sockSrv;/socket初始化DWORD CreateSocket()WSADATA WSAData;/WSADATA结构被用来保存函数WSAStartup返回的Windows Sockets初始化信息if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0)/WSAStartup完成winsock的初始化printf(socket initialize failed!n);return (-1);sockSrv=socket(AF_IN
5、ET,SOCK_STREAM,0);/定义为面向连接的,返回值送给sockSrvif(sockSrv=SOCKET_ERROR)printf(socket create failed ! n);WSACleanup();/中止Windows Sockets DLL的使用return(-1);SOCKADDR_IN addrSrv;/TCP/IP使用SOCKADDR_IN 定义地址addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);/计算机IP地址addrSrv.sin_port=htons(PORT);/协议端口号addrSrv.sin_family=
6、AF_INET;/地址所属协议簇/绑定端口if(bind(sockSrv,(struct sockaddr FAR *)&addrSrv,sizeof(addrSrv)=SOCKET_ERROR)printf(Bind Error);return(-1);return (1);int SendFileRecord(SOCKET datatcps,WIN32_FIND_DATA *pfd)/用于回复给客户端char filerecordMAX_PATH+32;FILETIME ft;FileTimeToLocalFileTime(&pfd-ftLastWriteTime,&ft);/将一个FIL
7、ETIME结构转换成本地时间 SYSTEMTIME lastwtime;/系统时间FileTimeToSystemTime(&ft,&lastwtime);/根据一个FILETIME结构的内容,装载一个SYSTEMTIME结构 char *dir=pfd-dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY?: ;sprintf(filerecord,%04d-%02d-%02d %02d:%02d %5s %10d %-20sn, lastwtime.wYear,lastwtime.wMonth,lastwtime.wDay,lastwtime.wHour,la
8、stwtime.wMinute,dir,pfd-nFileSizeLow,pfd-cFileName);if(send(datatcps,filerecord,strlen(filerecord),0)=SOCKET_ERROR)/发送回复失败printf(Error occurs when sending file list!n);return 0;return 1;/发送主机文件目录int SendFileList(SOCKET datatcps)HANDLE hff;WIN32_FIND_DATA fd; /获取和更改文件属性hff=FindFirstFile(*,&fd);/搜索文件i
9、f(hff=INVALID_HANDLE_VALUE)/搜索无效返回值const char *errstr=cant list files!n;coutlist file error!endl;if(send(datatcps,errstr,strlen(errstr),0)=SOCKET_ERROR)couterror occurs when sending file list!endl;closesocket(datatcps);return 0;BOOL fMoreFiles=TRUE;/BOOL型,返回值为大于0的整数时为TRUE,返回值为0时候,为FALSE,返回值为-1时为ERRO
10、R。while(fMoreFiles)/发送此项文件信息if(!SendFileRecord(datatcps,&fd)/发送失败closesocket(datatcps);return 0;/搜索下一个文件fMoreFiles=FindNextFile(hff,&fd);closesocket(datatcps);return 1;/发送数据int SendFile(SOCKET datatcps,FILE* file)/发送文件printf(sending file data.);for(;)/从文件中循环读取数据并发送客户端int r=fread(buf_send,1,1024,file
11、);if(send(datatcps,buf_send,r,0)=SOCKET_ERROR)printf(lost the connection to client!n);closesocket(datatcps);return 0;if(r1024)/文件传送结束break;closesocket(datatcps);printf(donen);return 1;DWORD ProcessCmd()if(listen(sockSrv,5)0)/监听信号coutListen error!endl;return(-1);coutListening for the requestendl;SOCK
12、ADDR_IN addrclient;/定义用于返回客户机端地址的结构int len=(sizeof(SOCKADDR_IN);while(1)SOCKET sockconn=accept(sockSrv,(SOCKADDR*)&addrclient,&len);/接受请求,产生新的套接字if(sockconn=INVALID_SOCKET)continue;else coutconnecting from clientendl;while(true)char filename20;memset(buf_rec,0,1024);memset(buf_send,0,1024);if(recv(s
13、ockconn,buf_rec,1024,0)=0)break; coutendlthe command is:buf_recendl;if(strncmp(buf_rec,dir,3)!=0&strncmp(buf_rec,get,3)!=0&strncmp(buf_rec,put,3)!=0)continue;/有一个请求正确执行下面语句if(strncmp(buf_rec,dir,3)=0)strcpy(buf_send,dir-ingn);send(sockconn,buf_send,1024,0);SendFileList(sockconn);/发送当前所有文件名/dirif (st
14、rncmp(buf_rec,get,3)=0) strcpy(filename,buf_rec+4);cout0)fwrite(buf_rec,sizeof(char),count,fd);fclose(fd);continue;/put 处理客户端的上传请求int main()CreateSocket();ProcessCmd();return(1);2. 客户端程序源代码:#include #include #include using namespace std;/使用名称空间std#pragma comment(lib, wsock32.lib)/将WinLib.lib库加入到工程中进
15、行编译#define PORT 4523/定义端口号为4523char send_str1024;char rec_str1024;char IP20;char filename20;SOCKET sockClient;SOCKADDR_IN addrServer;/定义表示地址的结构体addrServer,用来表示本地地址/创建套接字DWORD CreateSock()/本地信息addrServer.sin_family=AF_INET;/地址所属协议簇/AF表示ADDRESS FAMILY 地址族/ htons的功能:将一个无符号短整型数值转换为网络字节序addrServer.sin_po
16、rt=htons(PORT);/协议端口号WSADATA WSAData;/WSADATA结构被用来保存函数WSAStartup返回的Windows Sockets初始化信息WORD wVersionRequsdted;int err;wVersionRequsdted=MAKEWORD(2,2);err=WSAStartup(wVersionRequsdted,&WSAData);if(err!=0)printf(sock init fail!n);return(-1);coutplease input the IP of host:;scanf(%s,&IP);addrServer.sin
17、_addr.s_addr=inet_addr(IP);/计算机IP地址return(1);DWORD ConnectServer() /连接服务器sockClient=socket(AF_INET,SOCK_STREAM,0);/创建套接字,SOCK_STREAM为面向连接型if(sockClient=SOCKET_ERROR)printf(sock create fail! n);WSACleanup();/中止Windows Sockets DLL的使用.return(-1);if(connect(sockClient,(struct sockaddr *)&addrServer,size
18、of(addrServer)=SOCKET_ERROR)/如果请求建立连接错误printf(Connect fail n);memset(IP,0,20);return(-1);return(1);void help()couthelp List:endl;coutdirdirectory list endl;coutgetdownload filesendl;coutputupload files endl;coutquitexit !endl; /list读取服务器列表void list(SOCKET sock)int nRead;while(true)nRead=recv(sock,re
19、c_str,1024,0);/从一个套接口接收数据if(nRead=SOCKET_ERROR)coutread response error!endl;exit(1);if(nRead=0)/数据读取结束break;/显示数据rec_strnRead=0;printf(%s,rec_str);int SendFile(SOCKET datatcps,FILE* file)/SOCKET datatcps定义变量数据连接套接字 coutsending file data.endl;for(;)int r=fread(send_str,1,1024,file);/从一个流中读数据 if(send(
20、datatcps,send_str,r,0)=SOCKET_ERROR)printf(lost the connection to client!n);closesocket(datatcps);return 0;if(r1024)/文件传送结束break;closesocket(datatcps);/关闭接口printf(donen);return(1);int Cprocess()int count;char order10;char param20;char command30;FILE *fd;FILE *fd2;command0=0;CreateSock();ConnectServe
21、r();coutplease input order :order;strcat(command,order);if(strncmp(order,get,3)=0|strncmp(order,put,3)=0)/输入请求,有一个输入要求正确,输入目标文件名cinparam;strcat(command, );strcat(command,param);coutcommandendl;strcpy(send_str,command);if(send(sockClient,send_str,sizeof(send_str),0)0)coutsend data error!endl;closesoc
22、ket(sockClient);WSACleanup();return 0;recv(sockClient,rec_str,1024,0);/接受链接数据,放入rec_strcoutrec_str0)/接收文件,放入rec_strfwrite(rec_str,sizeof(char),count,fd);fclose(fd);/getif(strncmp(rec_str,put,3)=0)strcpy(filename,rec_str+9);/复制需发送的文件名称,赋给filenamefd2=fopen(filename,rb);if(fd2)/假如读文件成功if(!SendFile(sock
23、Client,fd2)/假如发送失败 printf(send failed!);return 0;fclose(fd2);else/打开文件失败strcpy(send_str,cant open file!n);if(send(sockClient,send_str,1024,0)return 0;/putclosesocket(sockClient);WSACleanup();return Cprocess();int main()help();Cprocess();return 0;5.程序运行结果一正确功能实现1. 运行客户端,输入服务器正确IP地址,连接成功后,输入dir查看服务器所在
24、文件夹中的文件 2. 用put命令发送文件p.txt,发送完毕,查看服务器所在文件夹,发现p.txt存在 二 运行错误测试1.运行客户端,输入错误的IP地址。输入请求后,显示框直接关闭6. 总结通过本次实验,我对网络命令有了一定的概念性认识,并熟悉了基本网络命令的使用,通过miniFTPClient/Server实验的实践,了解了SOCKET编程相关的一些知识以及用法,了解了客户端和服务器端进行通信的相关算法机制,在建立通信的基础上,实现了一些简单的功能。限于自己的能力,对SOCKET编程理解还不够透彻,对网络通信也只局限于miniFTPClient/Server实验的相关内容,还有待进一步的学习和实践以达到对网络的通信机制更深层次的理解