当前位置:文档之家› 文件传输程序设计讲解

文件传输程序设计讲解

Internet网络程序设计实验报告基于Socket的文件传输程序设计姓名:莫敌班级:软件 0904学号:U200917895指导老师:陆永忠2012.03.31目录1 实验目的及要求 (3)1.1 实验目的 (3)1.2 实验要求 (3)2 实验环境 (3)3 实验程序设计 (3)3.1 设计思想 (3)3.2 程序设计流程框图 (4)3.3 详细设计 (5)3.3.1 界面设计 (5)3.3.2 主要功能实现 (6)3.4 运行结果 (9)4 实验感想 (11)1实验目的及要求1.1实验目的熟悉Socket的通讯机制,了解网络程序的设计方法。

重点掌握基于TCP协议的Socket 网络编程。

1.2实验要求设计界面,在服务器端和客户端传输图片和文件。

如果是图片请显示该图片,如果是其他文件,则保存。

2实验环境编译环境:Windows 7 + Visual Studio 2010 使用MFC编写。

运行环境:Windows 7操作系统。

3实验程序设计3.1设计思想根据实验的要求:在服务器和客户端之间传输文件和图片,则需要程序提供一种可靠的网络传输服务来保证文件在传输过程中无丢失、损坏。

在分析了传输层协议TCP协议和UDP 协议后,了解到TCP协议提供的是一种面向连接的、可靠的字节流服务,而UDP协议提供的是一种无连接的、不可靠的数据报服务。

由于程序的需求,即必须保证文件传输的可靠性,于是,我采用基于TCP协议的Windows sockets来设计实现本实验。

3.2程序设计流程框图图1程序设计流程框图3.3详细设计基于TCP的socket编程流程:服务器端:创建套接字(socket)。

将套接字绑定到一个本地地址和端口上(bind)。

将套接字设为监听模式,准备接收客户端请求(listen)。

等待客户端请求到来。

当请求到来后,接收连接请求,返回一个新的对应于此次连接的套件字(accept)。

用返回的套接字和客户端进行通信(send/recv)。

返回,等待另一客户端请求。

关闭套接字。

客户端:创建套接字(socket)。

向服务器发出连接请求(connect)。

和服务器端进行通信(send/recv)。

关闭套接字。

3.3.1界面设计图2程序界面由于程序实现的功能单一简单,所以我的程序界面设计如图2所示。

程序由两个用户可操作的控件组成:IP地址控件,用户输入将要接收文件的接收方IP 地址;“发送文件”按钮,单击选择用户要发送的文件并发送所选文件数据。

3.3.2主要功能实现套接字库加载:AfxSocketInit()接收线程:UINT RecvProc( LPVOID pParam ){while (TRUE){CSocket tmpSock;CSocket servSock;tmpSock.Create(5000);tmpSock.Listen(1);tmpSock.Accept(servSock);char fileNameRecv[500] = {0};int a = servSock.Receive(fileNameRecv, 500);CFileDialog saveDlg(FALSE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "所有文件(*.*)|*.*||");saveDlg.m_ofn.lpstrFile = fileNameRecv;if (IDOK == saveDlg.DoModal()){CFile recvFile;CString recvPathName;recvPathName = saveDlg.GetPathName();recvFile.Open(recvPathName, CFile::modeCreate | CFile::modeWrite);UINT uiLength;servSock.Receive(&uiLength, 4);int iBufSize = 1024 * 5;int iSize = iBufSize;LPBYTE pBuf = new BYTE[iBufSize];int iNumByte;UINT uiTotal = 0;while (uiTotal < uiLength){if ((int)(uiLength - uiTotal) < iBufSize){iSize = uiLength - uiTotal;}int iCount = 0;while (iCount < iSize){iNumByte = servSock.Receive(pBuf, iSize - iCount);iCount += iNumByte;recvFile.Write(pBuf, iNumByte);}uiTotal += iCount;}recvFile.Close();servSock.Close();char ext[10];CString tmpExt;_splitpath(recvPathName, NULL, NULL, NULL, ext);tmpExt = ext;if(".bmp"== tmpExt || ".pcx"== tmpExt || ".tiff"== tmpExt || ".gif"== tmpExt || ".jpg" == tmpExt || ".jpeg" == tmpExt || ".tga" == tmpExt || ".exif" == tmpExt || ".fpx" == tmpExt){ShellExecute(NULL, "open", recvPathName, NULL, NULL, SW_SHOWNORMAL);}}}return 0;}发送文件按钮:void CmyFileTransferDlg::OnBnClickedBtnSend(){CFileDialog openDlg(TRUE, NULL, NULL, OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT, "所有文件(*.*)|*.*||");if (IDOK == openDlg.DoModal()){CString openFileName;openFileName = openDlg.GetFileName();CSocket sendSock;sendSock.Create();CString IPstr;this->GetDlgItem(IDC_IPADDRESS1)->GetWindowText(IPstr);if (sendSock.Connect(IPstr, 5000) == 0){return;}CFile sendFile;sendFile.Open(openDlg.GetPathName(), CFile::modeRead);sendSock.Send(openFileName, 500);UINT uiLength;uiLength = sendFile.GetLength();sendSock.Send(&uiLength, 4);int iBufSize = 1024 * 5;int iSize = iBufSize;LPBYTE pBuf = new BYTE[iBufSize];int iNumByte;UINT uiTotal = 0;while (uiTotal < uiLength){if ((int)(uiLength - uiTotal) < iBufSize){iSize = uiLength - uiTotal;}iSize = sendFile.Read(pBuf, iSize);int iCount = 0;while (iCount < iSize){iNumByte = sendSock.Send(pBuf, iSize - iCount);iCount += iNumByte;if (iCount < iSize){sendFile.Seek(iSize - iCount, CFile::current);}}uiTotal += iCount;}sendFile.Close();sendSock.Close();}3.4运行结果说明:为了便于测试和观察,选择127.0.0.1的发送IP地址进行单机测试。

图3程序运行启动界面双击打开myFileTransfer.exe可执行程序后的程序启动界面如图3所示,然后在“对方IP 地址”栏中输入本地回送地址127.0.0.1准备进行发送文件。

图4发送文件选择界面单击“发送文件”按钮后,弹出如图4所示的文件选择界面,选择要发送的文件并单击“打开”按键,确定选择并将所选文件发送给接收方。

图5接受方接收到文件当接收方接收到发送方传来的文件时,接收方程序弹出如图5所示的“保存”界面,提示用户接收文件成功并进行保存。

图6接收图片自动显示当接收方接收的文件为图片时,程序调用操作系统默认的图片浏览器自动打开浏览接收到的图片。

当接收的是非图片文件时,程序则只是保存该文件,而不自动打开。

4实验感想通过独立完成了这次实验的全部内容,我对网络编程有了更全面、深刻地认识和了解,尤其是对Windows socket的掌握和编程应用。

由于我对MFC较为熟悉,所以在整个实验过程中,我采用MFC进行编程来实现这个传输文件的程序。

在程序实现之前,我通过网络上的基于socket网络编程资料和老师课上讲解的内容,认真全面地学习了Windows socket的运行机制和其在网络编程上的应用方法。

在设计实现阶段,我最先使用的是基础SOCKET类,但在通信双方传送文件的基本信息的具体实现时,遇到了不少的麻烦。

比如SOCKET类中的send方法的第二个参数类型是“const char *”用来指明一个存放将要发送数据的缓冲区,但在传文件信息长度int类型等非char *的变量时转化很麻烦。

于是,我查看MSDN文档了解到MFC已为开发者封装了一个很简便的CSOCKET类。

应用CSOCKET类能很方便容易地解决上面的问题,而且实现网络通信的流程也很清晰,最终我采用MFC封装的CSOCKET类编码实现的这次实验内容。

在接收图片自动显示的问题上,我试验了两种实现方式:用一个MFC中的承托图片控件来显示和调用操作系统默认的图片浏览程序来显示,对比操作效果和用户使用习惯,后者的解决方案更好,所以最终我采用调用操作系统默认的图片浏览程序来对图片文件进行自动打开显示。

相关主题