版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
课程设计课程名称______________________题目名称______________________学生学院______________________专业班级______________________学号______________________学生姓名______________________指引教师______________________200年月日摘要本课程设计阐明书重要阐明了在windows下如何用c语言编写设计ftp服务器和客户端基本办法及其实现。包括了TCP/IP合同基本通信原理,Winsock编程基本原理以及ftp工作原理。正文某些是程序设计详细内容及其源代码,最后是报告反思及总结。核心词:TCP/IP,Winsock,ftpTOC\o"1-3"\u摘要 11.绪论 11.1设计目 11.2设计规定 11.21计算机网络实验环境建立在TCP/IP网络体系构造之上。 11.22详细规定 11.3设计准备 21.4设计方案 22.开发环境简介 23.有关原理分析理解 33.1TCP/IP原理 33.11网络层合同 33.12应用层合同 33.2Winsock编程原理 33.23Winsock编程模型: 4数据报套接字编程模型 4WinsockI/O模型 53.3TP工作原理 53.4WinsockAPI基本函数简介 5(1)WSAStartup()函数和WSACleanup()函数 5(2)socket()函数 6(3)bind()函数 6(4)listen()函数 6(5)accept()函数 6(6)connect()函数 6(7)closesocket()函数 74.总体设计 74.1理解Winsock与操作系统关系 74.2实现功能流程图 85.详细设计 85.1文献传播源程序代码 8(1)客户端client程序代码 8(2)、服务器端server程序代码 14六、系统实现环节 19七、总结结论(心得体会) 21参照文献: 221.绪论1.1设计目本设计旨在运用原始socket简朴实现FTP(FileTransferProtocol,文献传播合同)客户端和服务器端程序,可以实现get、put、pwd、dir、cd等基本交互命令。通过完毕此设计,理解WinsockAPI函数调用办法和普通网络应用程序编程办法,理解FTP合同,掌握C语言设计FTP合同软件基本技术,为将来开发其她通信合同软件打下坚实基本。1.2设计规定1.21计算机网络实验环境建立在TCP/IP网络体系构造之上。各计算机除了安装TCP/IP软件外,还安装了TCP/IP开发系统。实验室各计算机具备Windows环境中套接字socket编程接口功能,可为顾客提供全网范畴进程通信功能。本实验规定学生运用这些功能,设计和实现一种简朴文献传送合同。1.22详细规定用socket编程接口编写两个程序,分别为客户程序(client.c)和服务器程序(server.c),该程序应能实现下述命令功能:get:取远方一种文献put:传给远方一种文献pwd:显示远主当前目录dir:列出远方当前目录cd:变化远方当前目录 ?:显示你提供命令quit:退出返回1.3设计准备装有Windows操作系统PC机、VisualC++6.0编译器或VS编译器1.4设计方案1.服务器端调用socketaccept()办法,等待客户端联接。2.客户端发送需要从服务端获得文献夹途径给服务器端。3.服务器端依照客户端发来途径遍历整个途径下文献及文献夹,并将需要传送到文献记录全途径记录到一种String类型数组中,并将文献个数发送给客户端。4.客户端接受服务器端发来文献个数,并向服务器端发送关闭联接祈求,并关闭客户端连接。5.服务器端收取关闭连接祈求,将socket关闭,进入传播文献循环中。6.服务器端调用socketaccept()办法,等待客户端联接。7.客户端依照刚才获得要传播文献数,进行循环获取文献,记得每次取完文献要关闭socket连接,这样就不会将各种文献写入到同一种文献中。2.开发环境简介VC6.0编程环境:一方面建一种工程,填入文献名,点击下一步,浮现要创立文献夹名,填上点击下一步,完毕建立工程。然后再点击新建菜单,新建一种C/C++source文献,点击下一步,完毕建立过程,然后在窗口中写入源代码,执行即可。3.有关原理分析理解3.1TCP/IP原理TCP合同和IP合同指两个用在Internet上网络合同(或数据传播办法)。它们分别是传播控制合同和互连网合同。这两个合同属于众多TCP/IP合同组中一某些。TCP/IP合同组中合同保证Internet上数据传播,提供了几乎当前上网所用到所有服务。这些服务涉及:电子邮件传播,文献传播,新闻组发布,访问万维网在TCP/IP合同组分两种合同:网络层合同和应用层合同3.11网络层合同:网络层合同管理离散计算机间数据传播。这些合同顾客注意不到,是在系统表层如下工作。例如,IP合同为顾客和远程计算机提供了信息包传播办法。它是在许多信息基本上工作,例如说是机器IP地址。在机器IP地址和其他信息基本上,IP保证信息包能对的地到达目机器。通过这一过程,IP和其他网络层合同共同用于数据传播。如果没有网络工具,顾客就看不到在系统里工作IP。3.12应用层合同:相反地,应用层合同顾客是可以看得到。例如,文献传播合同(FTP)顾客是看得到。顾客为了传播一种文献祈求一种和其他计算机连接,连接建立后,就开始传播文献。在传播时,顾客和远程计算机互换一某些是能看到。TCP/IP通过使用合同栈工作。这个栈是所有用来在两台机器间完毕一种传播所有合同几种集合。(这也就是一种通路,数据通过它从一台机器到另一台机器。)栈提成层,与这里关于是五个层。栈每一层都能从相邻层中接受或发送数据。每一层都与许多合同相联系。在栈每一层,这些合同都在起作用。本章下一某些将分析这些服务,以及它们在栈中是如何联系。同步也分析一下它们功能,它们提供服务和与安全性关系。3.2Winsock编程原理通过Winsock可实现点对点或广播通信程序,实际这两者之间区别不大,编程时其程序流程所用代码几乎相似,不同地方在于目的地址选取不同。由于Winsock服务是以动态链接库WinsockDLL形式实现,因而先调用1、WSAStartup对WinsockDLL进行初始化2、应用程序关闭套接字后,还应调用WSACleanup终结对WinsockDLL使用3.23Winsock编程模型:流套接字编程模型:1.服务器进程创立套接字socket2.将本地地址绑定到所创立套接字bind3.将套接字置入监听模式并准备接受连接祈求listen,accept4.客户进程调用socket函数创立客户端套接字5.客户向服务进程发出连接祈求connect6.当服务器接受到客户祈求,阻塞accept进程,生成新一种新套接字与客户套接字建立连接,并向客户端返回接受信号7.客户套接字收到服务器接受信号,表达连接建立成功,开始用send,recv进行收发数据8关闭套接字先用shutdown再用closesocket数据报套接字编程模型:服务器用socket创立,用bind绑定用readfrom从网络上接受,收不到进入阻塞客户端也用socket,bind绑定客户端用sendto发送数据服务器端接受数据,用sendto进行响应⑥数据发送完两者调用closesocket进行套接字释放WinsockI/O模型:阻塞模式:始终等待下去,不会及时返回非阻塞模式:无论何都会返回关交出程序控制权3.3TP工作原理文献传播合同是从一种系统向另一种系统传递文献原则办法。它目的在RFC0765中写得很清晰。FTP目的1)增进文献和程序共享2)勉励间接和含蓄使用远程计算机3)使顾客不必面对主机间使用不同文献存储系统4)有效和可靠地传播文献。FTP,尽管顾客可以直接通过终端来使用,是设计成让别程序使用。FTP文献传播应用在客户/服务环境。祈求机器启动一种FTP客户端软件。这就给目的文献服务器发出了一种祈求。典型地,这个规定被送到端口21。一种连接建立起来后,目的文献服务器必要运营一种FTP服务软件。FTPD是原则FTP服务daemon。它功能很简朴:回答inetd收到连接祈求,并满足这些要传播文献祈求。这个daemon在许多发行版UNIX中是个原则。FTPD等待一种连接祈求。当这样一种祈求到达时,FTPD祈求顾客登录。顾客提供它合法登录名和口令或匿名登录。一旦登录成功,顾客可如下载文献了。在某些状况下,如果服务器安全容许,顾客可以上载文献。3.4WinsockAPI基本函数简介(1)WSAStartup()函数和WSACleanup()函数由于Winsock2提供API服务是以动态链接库ws2_32.dll实现,因此必要先调用WSAStartup()函数对ws2_32.dll进行加载初始化,协商Winsock版本支持,并分派必要资源。在应用程序关闭套接字后,还应调用WSACleanup()函数来终结和卸载动态链接库ws2_32.dll,释放资源。(2)socket()函数服务进程和客户进程在通信前必要创立各自套接字,然后才干用相应套接字进行发送、接受操作,实现数据传播。服务进程总是先于客户进程启动,服务进程和客户进程调用socket()函数创立套接字。(3)bind()函数当用socket()创立套接字后,它便存在于一种名字空间(地址族)中,但并未赋名。bind()函数通过给一种未命名套接字分派一种本地名字(主机地址/端标语)来为套接字建立本地捆绑。客户端普通隐式地向操作系统祈求一种随机未使用过暂时端标语,跟自己IP地址一起,与所创立套接字建立联系,由于该暂时端标语客户端程序事先是不拟定,因而不显式地使用绑定函数。(4)listen()函数调用listen()函数对服务器上套接字启动监听,即容许客户连接祈求开始排队。(5)accept()函数服务器设立监听工作方式后,通过调用accept()函数使套接字等待接受客户连接。如果已有连接祈求到来,该函数会返回一种新套接字描述符,它相应于已经接受那个客户端连接。对于该客户机后续所有操作,都应使用这个新套接字。至于本来那个监听套接字,它依然用于接受其她客户机连接,继续处在监听模式。(6)connect()函数客户端运用connect()函数和服务器建立一种端到端连接。(7)closesocket()函数网络通信任务完毕后,运用本函数释放套接字占用所有资源。4.总体设计4.1理解Winsock与操作系统关系4.2实现功能流程图
5.详细设计5.1文献传播源程序代码(1)客户端client程序代码#include"Winsock.h"#include"windows.h"#include"stdio.h"#include"time.h"#include<iostream.h>#defineRECV_PORT3312#defineSEND_PORT4302#pragmacomment(lib,"wsock32.lib")SOCKETsockclient;charfilename[20];//文献名sockaddr_inServerAddr; //服务器地址charrbuff[1024]; //接受缓冲区charsbuff[1024]; //发送缓冲区charInputIP[20]; //存储输入服务器IPvoidhelp(){//解决help命令 cout<<"欢迎进入迷你FTP协助菜单"<<endl <<"*********************"<<endl <<"1.get下载(接受)文献"<<endl <<"get用法:get文献名"<<endl<<endl <<"2.put上传(发送)文献"<<endl <<"put用法:put文献名"<<endl <<"3.pwd显示当前文献夹绝对途径"<<endl <<"4.dir显示远方当前目录文献"<<endl<<endl <<"5.cd变化远方当前目录和途径"<<endl <<"cd用法(进入下级目录):cd途径名"<<endl <<"cd用法(进入上级目录):cd.."<<endl<<endl <<"6.?或者help进入协助菜单"<<endl <<"7.quit退出FTP"<<endl <<"*********************"<<endl;}/************************dir:列出远方当前目录**********************/voidlist(SOCKETsockfd){intnRead; while(true) { nRead=recv(sockclient,rbuff,1024,0); //recv函数通过sockclient套接口接受数据存入rbuff缓冲区,返回接受到字节数 if(nRead==SOCKET_ERROR) {printf("readresponseerror!\n"); exit(1); } if(nRead==0)//数据读取结束 break; //显示数据 rbuff[nRead]='\0'; printf("%s",rbuff); }}/***********************put:传给远方一种文献***************************/intSendFile(SOCKETdatatcps,FILE*file){ printf("sendingfiledata.."); for(;;)//从文献中循环读取数据并发送客户端 { intr=fread(sbuff,1,1024,file);//fread函数从file文献读取1个1024长度数据到sbuff,返回成功读取元素个数 if(send(datatcps,sbuff,r,0)==SOCKET_ERROR) { printf("losttheconnectiontoclient!\n"); closesocket(datatcps); return0; } if(r<1024)//文献传送结束 break; } closesocket(datatcps); printf("done\n"); return1;}DWORDStartSock()//启动winsock{ WSADATAWSAData; chara[20]; memset(a,0,20); if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0)//加载winsock版本 { printf("sockinitfail!\n"); return(-1);} if(strncmp(InputIP,a,20)==0) { printf("请输入连接主机IP:"); scanf("%s",&InputIP); }//设立地址构造 ServerAddr.sin_family=AF_INET;//AF_INET表达使用IP地址族 ServerAddr.sin_addr.s_addr=inet_addr(InputIP);//指定服务器IP ServerAddr.sin_port=htons(RECV_PORT);//设立端标语 return(1);}//创立套接字DWORDCreateSocket(){ sockclient=socket(AF_INET,SOCK_STREAM,0);//当socket函数成功调用时返回一种新SOCKET(SocketDescriptor) if(sockclient==SOCKET_ERROR) {printf("sockclientcreatefail!\n"); WSACleanup(); return(-1); } return(1); } DWORDCallServer()//发送连接祈求 { CreateSocket(); if(connect(sockclient,(structsockaddr*)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR)//connect函数创立与指定外部端口连接 { printf("Connectfail\n"); memset(InputIP,0,20); return(-1); } return(1);}DWORDTCPSend(chardata[])//发送命令{ intlength; length=send(sockclient,data,strlen(data),0);//send函数通过sockclient接口发送data里面数据,发送成功返回发送字节数 if(length<=0) { printf("senddataerror!\n"); closesocket(sockclient); WSACleanup(); return(-1); } return(1);}intmain(){ charmessge1[10]; //定义输入要解决文献名 charmessge2[20]; //定义输入要解决文献名 charorder[30]; //输入命令 order[0]='\0'; charbuff[80]; //用以存储通过字串格式化order FILE*fd; //File合同重要用于访问本地计算机中文献,fd指针指向要访问目的文献 FILE*fd2; intcount; intsin_size=sizeof(ServerAddr); StartSock(); if(CallServer()==-1) returnmain(); //发送连接祈求失败,返回主函数 printf("\n请输入命令(输入?或help进入协助菜单):\n"); memset(buff,0,80); //清空数组 memset(messge2,0,20); memset(order,0,30); memset(messge1,0,10); memset(rbuff,0,1024); memset(sbuff,0,1024); scanf("%s",&messge1); if(strncmp(messge1,"get",3)==0) scanf("%s",&messge2); if(strncmp(messge1,"put",3)==0) scanf("%s",&messge2); if(strncmp(messge1,"cd",2)==0) scanf("%s",&messge2); strcat(order,messge1); //把messge1加在order末尾 strcat(order,""); //命令中间空格 strcat(order,messge2); //把messge2加在order末尾 sprintf(buff,order); //把调节格式order存入buff //help和? if(strncmp(messge1,"help",4)==0){ help(); } if(strncmp(messge1,"?",1)==0){ help(); } if(strncmp(messge1,"quit",4)==0) { printf("欢迎再次进入迷你FTP,谢谢使用!\n"); closesocket(sockclient); WSACleanup(); return0; } TCPSend(buff);//发送buff里面数据 recv(sockclient,rbuff,1024,0); printf(rbuff); if(strncmp(rbuff,"get",3)==0)//get { fd=fopen(messge2,"wb");//使用二进制方式,打开文献,wb只写打开或新建一种二进制文献;只容许写数据。 if(fd==NULL) { printf("openfile%sforweitefailed!\n",messge2); return0; } while((count=recv(sockclient,rbuff,1024,0))>0) { fwrite(rbuff,sizeof(rbuff),count,fd); } //把count个数据长度为size0f()数据从rbuff输入到fd指向目的文献 fclose(fd);//关闭文献 } if(strncmp(rbuff,"put",3)==0)//put { strcpy(filename,rbuff+9); fd2=fopen(filename,"rb");//rb读写打开一种二进制文献,只容许读写数据。 if(fd2) { if(!SendFile(sockclient,fd2)){ printf("sendfailed!"); return0; } fclose(fd2);}//关闭文献 else//打开文献失败 { strcpy(sbuff,"can'topenfile!\n"); if(send(sockclient,sbuff,1024,0)) return0; } } if(strncmp(rbuff,"dir",3)==0) //dir { printf("\n"); list(sockclient); //列出接受到列表内容 } if(strncmp(rbuff,"pwd",3)==0) { list(sockclient); //列出接受到内容--绝对途径 } if(strncmp(rbuff,"cd",2)==0){} //cd closesocket(sockclient); //关闭连接 WSACleanup(); //释放Winsock returnmain();}(2)、服务器端server程序代码#include"Winsock.h"#include"windows.h"#include"stdio.h"#defineRECV_PORT3312#defineSEND_PORT4302#pragmacomment(lib,"wsock32.lib")SOCKETsockclient,sockserver;sockaddr_inServerAddr;//服务器地址sockaddr_inClientAddr;//客户端地址/***********************全局变量***********************/intAddrlen;//地址长度charfilename[20];//文献名charorder[10];//命令charrbuff[1024];//接受缓冲区charsbuff[1024];//发送缓冲区DWORDStartSock()//初始化winsock{ WSADATAWSAData; if(WSAStartup(MAKEWORD(2,2),&WSAData)!=0) { printf("socketinitfail!\n"); return(-1); } return(1);}DWORDCreateSocket(){ sockclient=socket(AF_INET,SOCK_STREAM,0); if(sockclient==SOCKET_ERROR) { printf("sockclientcreatefail!\n"); WSACleanup(); return(-1); } ServerAddr.sin_family=AF_INET; ServerAddr.sin_addr.s_addr=htonl(INADDR_ANY); ServerAddr.sin_port=htons(RECV_PORT); if(bind(sockclient,(structsockaddrFAR*)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR) {//bind函数将套接字和地址构造绑定 printf("bindistheerror"); return(-1); } return(1);}intSendFileRecord(SOCKETdatatcps,WIN32_FIND_DATA*pfd)//用来发送当前文献记录{ charfilerecord[MAX_PATH+32]; FILETIMEft;//文献建立时间 FileTimeToLocalFileTime(&pfd->ftLastWriteTime,&ft); SYSTEMTIMElastwtime;//SYSTEMTIME系统时间数据构造 FileTimeToSystemTime(&ft,&lastwtime); char*dir=pfd->dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY?"<DIR>":""; sprintf(filerecord,"%04d-%02d-%02d%02d:%02d%5s%10d%-20s\n", lastwtime.wYear, lastwtime.wMonth, lastwtime.wDay, lastwtime.wHour, lastwtime.wMinute, dir, pfd->nFileSizeLow, pfd->cFileName); if(send(datatcps,filerecord,strlen(filerecord),0)==SOCKET_ERROR) {//通过datatcps接口发送filerecord数据,成功返回发送字节数 printf("Erroroccurswhensendingfilelist!\n"); return0; } return1;}intSendFileList(SOCKETdatatcps){ HANDLEhff;//建立一种线程 WIN32_FIND_DATAfd;//搜索文献 hff=FindFirstFile("*",&fd);//可以通过FindFirstFile()函数依照当前文献存储途径查找该文献来把待操作文献有关属性读取到WIN32_FIND_DATA构造中去: if(hff==INVALID_HANDLE_VALUE)//发生错误 { constchar*errstr="can'tlistfiles!\n"; printf("listfileerror!\n"); if(send(datatcps,errstr,strlen(errstr),0)==SOCKET_ERROR) { printf("erroroccurswhensengingfilelist!\n"); } closesocket(datatcps); return0; } BOOLfMoreFiles=TRUE; while(fMoreFiles) {//发送此项文献信息 if(!SendFileRecord(datatcps,&fd)) { closesocket(datatcps); return0; } //搜索下一种文献 fMoreFiles=FindNextFile(hff,&fd); } closesocket(datatcps); return1;}intSendFile(SOCKETdatatcps,FILE*file){ printf("sendingfiledata.."); for(;;)//从文献中循环读取数据并发送客户端 { intr=fread(sbuff,1,1024,file);//把file里面内容读到sbuff缓冲区 if(send(datatcps,sbuff,r,0)==SOCKET_ERROR) { printf("losttheconnectiontoclient!\n"); closesocket(datatcps); return0; } if(r<1024)//文献传送结束 break; } closesocket(datatcps); printf("done\n"); return1;}//连接DWORDConnectProcess(){ Addrlen=sizeof(sockaddr_in); if(listen(sockclient,5)<0) { printf("Listenerror"); return(-1); } printf("服务器监听中...\n"); for(;;) { sockserver=accept(sockclient,(structsockaddrFAR*)&ClientAddr,&Addrlen); //accept函数取出连接队列第一种连接祈求,sockclient是处在监听套接字ClientAddr是监听对象地址, //Addrlen是对象地址长度 for(;;) { memset(rbuff,0,1024); memset(sbuff,0,1024); if(recv(sockserver,rbuff,1024,0)<=0) { break; } printf("\n"); printf("获取并执行命令为:"); printf(rbuff); if(strncmp(rbuff,"get",3)==0) { strcpy(filename,rbuff+4);printf(filename); FILE*file;//定义一种文献访问指针 //解决下载文献祈求 file=fopen(filename,"rb");//打开下载文献,只容许读写 if(file) { sprintf(sbuff,"getfile%s\n",filename); if(!send(sockserver,sbuff,1024,0)) { fclose(file);return0; } else {//创立额外数据连接传送数据 if(!SendFile(sockserver,file)) return0; fclose(file); } }//file else//打开文献失败 { strcpy(sbuff,"can'topenfile!\n"); if(send(sockserver,sbuff,1024,0)) return0; }//lost }//get if(strncmp(rbuff,"put",3)==0) { FILE*fd; intcount; strcpy(filename,rbuff+4); fd=fopen(filename,"wb"); if(fd==NULL) {
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年烟草专卖知识测试题及答案
- 高中跨学科专题2025文化遗产保护说课稿
- 2026年九重人格测试题及答案
- 2026年妇婴护理测试题及答案
- 4.2 调控测试说课稿2025学年高中信息技术人教中图版2019选修6 开源硬件项目设计-人教中图版2019
- 安全培训管理表格模板
- 4 波的反射和折射说课稿2025学年高中物理苏教版选修3-4-苏教版2014
- 初中2025感谢师恩主题班会说课稿
- 2026年说课稿思路说明音乐
- 初中生适应能力说课稿2025
- 肺部磁共振成像在肺疾病诊断中的价值
- 初中八年级数学课件-一次函数的图象与性质【全国一等奖】
- 《石墨类负极材料检测方法 第1部分:石墨化度的测定》
- 贵州艺辰纸业有限责任公司年产15万吨化学机械木浆的林纸一体化生产线及配套的纸板生产线(一期)环评报告
- 鳞翅目检疫性害虫课件
- 硬笔书法 撇和捺的写法课件
- JJG 444-2023标准轨道衡
- 羽毛球正手击高远球教学设计
- GB/T 15530.6-2008铜管折边和铜合金对焊环松套钢法兰
- GRR培训-完整版课件
- 重庆普通专升本英语真题09-18
评论
0/150
提交评论