基于TCP的文件传输程序

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

《计算机网络系统实践》报告2015年12月设计题目:网络文件传输学生姓名:郑波学号:2013211644专业班级:计算机科学与技术13-2班一、设计要求1、实现单线程文件传输功能2、在以上的基础上,掌握多线程技术,在文件网络传输时,可选择单线程或多线程3、加入异常控制机制,增强程序的鲁棒性(Robust)4、了解如何提高套接字传输的速率,以及如何加强传输的稳定性二、开发环境与工具Windows7下MicrosoftVisualStuio三、设计原理1、网络传输协议TCP/IP协议栈中的两个协议:TCP(TransmissionControlProtocol):传输控制协议UDP(UserDatagrmProtocal):用户数据报协议TCP是面向连接的通信协议,TCP提供两台计算机之间的可靠无错的数据传输。应用程序利用TCP进行通信时,源和目标之间会建立一个虚拟连接。该连接一旦建立,两台计算机之间就可以把数据当做一个双向字节流进行交换。UDP是无连接的通信协议,UDP不保证可靠数据的传输,但能够向若干个目标发送数据,接受发自若干个源的数据。就是说,如果一个主机向另外一台主机发送数据,这个数据就会立即发出,而不管另外一台主机是否已准备接收数据。如果另外一台主机接收到了数据,它不会确认收到与否。本次工程目的是传输文件,显然需要用TCP建立连接,而TCP连接需要“三次握手”。2、三次握手三次握手具体过程:1、客户端主动与服务器联系,TCP首部控制位中的SYN设置为1,发送带有SYN的TCP段,并把初始序号告诉对方2、服务端收到带有SYN的报文,记录客户端的初始序号,选择自己的初始序号,设置控制位中的SYN和ACK。因为SYN占用一个序号,所以确认序号设置为客户端的初始序号加1,对客户端的SYN进行确认3、服务端的报文到达客户端,客户端设置ACK控制位,并把确认好设为服务器的初始序号加1,以确认服务器的SYN报文段,这个报文只是确认消息,告诉服务器已经成功建立了连接四、系统功能描述及软件模块划分1、系统功能描述软件实现了点对点的文件传输。传输前的接收提醒以及传输过程中的控制。2、软件模块划分本程序可以划分成以上三个模块:传输控制模块,文件传输模块和服务连接模块。其中:服务连接模块用来建立客户端到服务器的连接文件传输模块主要用两个线程:_SendThread和_ListenThread来完成,实现发送和接收文件的功能。传输控制模块主要通过封装好的可串行化信息类CMessage互相传递两端的文件操作消息,响应“暂停传输”,“关闭连接”等功能五、设计步骤1、服务连接模块先要建立起客户端与服务器之间的连接,大致过程如下:①服务器启动:if(m_nServerType==SERVER){//创建服务器套接字m_psockServer=newCListenSocket(this);if(!m_psockServer-Create(m_wPort))//绑定端口{deletem_psockServer;m_psockServer=NULL;MessageBox(GetError(GetLastError()),_T(错误),MB_ICONHAND);return;}//开启线程,监听客户端连接if(!m_psockServer-Listen()){deletem_psockServer;m_psockServer=NULL;MessageBox(GetError(GetLastError()),_T(错误),MB_ICONHAND);return;}}②客户端填入相应的IP地址,连接服务器if(((CIPAddressCtrl*)GetDlgItem(IDC_IPADDRESS))-IsBlank()){MessageBox(IP地址不能为空,错误,MB_ICONHAND);return;}//创建客户端套接字m_psockClient=newCClientSocket(this);if(!m_psockClient-Create()){deletem_psockClient;m_psockClient=NULL;MessageBox(GetError(GetLastError()),_T(错误),MB_ICONHAND);return;}//与服务器建立连接CStringstrIPAddress;GetDlgItem(IDC_IPADDRESS)-GetWindowText(strIPAddress);if(!m_psockClient-Connect(strIPAddress,m_wPort))//Connect连接服务器,服务器用OnAccept响应{deletem_psockClient;m_psockClient=NULL;MessageBox(GetError(GetLastError()),_T(错误),MB_ICONHAND);return;}//初始化客户端套接字m_psockClient-Init();③服务器响应CClientSocket*pSocket=newCClientSocket(this);//接收请求后获得新的套接字,交由新的套接字处理请求if(m_psockServer-Accept(*pSocket))//非零则接收连接请求成功{//初始化Accpet返回的套接字pSocket-Init();CMessage*pMsg;//检测套接字是否为空,空则还没有连接任何客户端if(m_psockClient==NULL){pMsg=newCMessage(CONNECT_BE_ACCEPT);pSocket-SendMsg(pMsg);//发回“这边可以连接”消息回去,客户端的Receive接收m_psockClient=pSocket;//若为服务器,则之前未初始化,可保存这个套接字,用来跟客户端交互GetDlgItem(IDC_SELECT_FILE)-EnableWindow(TRUE);}else{pMsg=newCMessage(CONNECT_BE_REFUSE);pSocket-SendMsg(pMsg);}}④客户端收到连接成功消息if(pMsg-m_nType==CONNECT_BE_ACCEPT){GetDlgItem(IDC_SELECT_FILE)-EnableWindow(TRUE);return;}2、传输控制模块该工程用了两对套接字,一对用来接收传输控制消息,一对用来收发文件。我们这个模块用的是第一对在MFC中定义了一个在套接字编程中使用的CSocketFile类,可以充分发挥CSocket类的特性。CSocketFile类是CFile的派生类,主要用来在WindowsSockets编程中发送和接收序列化数据(如结构体数据)。通过把CSocketFile类对象、CArchive对象和CSocket创建的套接字对象联系起来,可以实现数据的加载(接收)和存储(发送)。MFC集成CSocketFile、CSocket、CArchive可以简化网络传输。下图可以直观地反应这三者是如何结合来在客户端和服务器之间传输消息的先来看看服务器和客户端的套接字初始化工作:m_pFile=newCSocketFile(this);m_pArchiveIn=newCArchive(m_pFile,CArchive::load);m_pArchiveOut=newCArchive(m_pFile,CArchive::store);这样一来,当使用m_pArchiveIn对象来调用可串行化消息类CMessage的Serialize时,接收方就能响应OnReceive消息,来完成控制信息的传递。本工程在主类CsendFileDlg中定义了传输的三种状态:m_bIsWait:已连接,正在等待传输文件m_bIsTransmitting:正在传输文件m_bIsStop:传输已终止本工程定义的可串行化消息类CMessage,用来传递文件名m_strFileName、文件长度m_dwFileSize以及当前的传输状态m_nType,大致流程如下图:其中,我在建工程的时候,把客户端和服务器集成在了一个界面OnReceive就用来接收两方的消息,关键代码如下:CMessage*pMsg=newCMessage();pSocket-ReceiveMsg(pMsg);if(pMsg-m_nType==CONNECT_BE_ACCEPT){GetDlgItem(IDC_SELECT_FILE)-EnableWindow(TRUE);return;}if(pMsg-m_nType==CONNECT_BE_REFUSE){MessageBox(_T(服务器正在和另外的客户端连接,稍等),_T(错误),MB_ICONHAND);deletem_psockClient;m_psockClient=NULL;return;}if(pMsg-m_nType==DISCONNECT){MessageBox(_T(对方已经关闭),_T(警告),MB_ICONHAND);if(m_psockClient!=NULL){deletem_psockClient;m_psockClient=NULL;}}//接收请求if(pMsg-m_nType==REQUEST){m_bIsWait=TRUE;//忙状态置1m_strFileName=pMsg-m_strFileName;m_dwFileSize=pMsg-m_dwFileSize;CStringstrName,strSize;strName.Format(文件名:%s,m_strFileName);strSize.Format(文件大小:%ld字节,strSize);//这里完成了发送文件前给对方提示的功能if(MessageBox(strName+\r\n+strSize,对方请求向你发送文件,MB_OKCANCEL)==IDCANCEL){CMessage*pMsg=newCMessage(REFUSE);m_psockClient-SendMsg(pMsg);return;}CFileDialogdlg(FALSE,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,所有文件(*.*)|*.*||,this);dlg.m_ofn.lpstrTitle=_T(另存为);strcpy(dlg.m_ofn.lpstrFile,m_strFileName.GetBuffer(m_strFileName.GetLength()));if(dlg.DoModal()==IDOK){if(m_bIsWait==FALSE){MessageBox(_T(对方已经取消文件发送),_T(警告),MB_ICONEXCLAMATION);return;}m_bIsClient=FALSE;m_strPath=dlg.GetPathName();//启动接收文件的线程GetDlgItem(IDC_SR)-SetWindowText(已接收:);pThreadListen=::AfxBeginThread(_ListenThread,this);//服务器接收到RUEST,开启接收文件线程return;}if(m_bIsWait==TRUE){//告诉对方文件发送请求被拒绝CMessage*pMsg=newCMessage(REFUSE);m_psockClient-SendMsg(pMsg);}m_bIsWait=FALSE;return;}//当对方同意,并且已经准备好接收文件的时候if(pMsg-m_nType==ACCEPT){KillTimer(1);m_bIsWait=FALSE;//等待状态清空//启动发送文件线程GetDlgItem(IDC_SR)-SetWindowText(已发送:);pThrea

1 / 32
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功