
1 理论知识(一级标题,黑体四号,加粗,单倍行距,段前后6磅)
1.1 传输文件工具工作原理分析(二级标题,宋体四号,加粗,单倍行距,段前后6磅)
程序使用的是基于TCP/IP的协议,用套接字来实现文件的传输。
1.1.1 TCP/IP的网络体系结构
TCP/IP协议采用层次体系结构,如图2所示,从图中可以看出,每一层在逻辑上都与通信端的对应层相连接。图中所示的服务器程序持续监听通信客户端;客户端仅周期性地与服务器相连接以交换数据,其中TCP协议层提供相当于OSI参考模型中传输层的服务,为收、发端应用程序提供通信;IP协议层负责提供统一的数据报;链路层主要功能是收、发IP层的IP数据报;TCP/IP之上是该协议提供的各种服务,而底层网络可以是不同的物理网络,如Ethernet、Token Ring、X.25公共分组交换网等。
图1 TCP/IP协议层模型(LAN)
1.1.2 套接字(Sockets)
套接字(Sockets)最早是由Berkeley大学提出在UNIX操作系统下实现TCP/IP通信协议的开发接口,随着Internet在全球范围内的广泛使用,Sockets已成为网络编程的通用接口。Microsoft公司以Sockets为基础开发的Winsock建立了Windows环境下网络间的编程接口。
套接字是对网络中不同主机上应用进程之间进行双向通信的端点的抽象,一个套接口就是网络上进程通信的一端,提供了应用层进程利用网络协议栈交换数据的机制。套接字可以分为流式套接字(Stream Sockets)、数据报套接字(Datagram Sockets)和原始套接字(Raw Sockets)。流式套接字最常用的套接字,提供面向连接的、无差错的、发送顺序一致的、包长度不限和非重复的网络信息的传输;数据报套接字提供无连接的服务,以的数据报进行传输,不保证顺序性、可靠性和无重复性;原始套接字提供对下层网络的通信协议的访问,主要用于开发新的协议或用于提取较隐蔽的功能。
在程序设计中我们选择流式套接字搂完成C/S模式的通信,保证数据能够准确、无误的传输。图2所示的是流式套接字的基本通信方式。
图2 面向连接的流方式
1.2.3 传输原理
应用程序的网络通信是利用相同的通途协议来完成信息的传输。应用程序和Winsock都是工作在Windows的用户模式下,操作系统不仅仅通过Winsock,还需要底层的支持。套接字仿真器(套接字核心驱动程序)和传输驱动程序接口,起到了Winsock和传输协议之间的通信桥梁作用。如图3所示,Winsock是网络通信应用程序于套接字仿真器间的接口,TDI是套接字仿真器和传输协议间的接口套接字核心模式,驱动程序复杂连接和缓冲区管理,以便向应用程序提供套接字仿真(在AFDSYS文件中实现),同时负责与底层传输驱动程序对话传输驱动程序接口(TDI)负责核心模式驱动程序与传输协议间的通信。
图3 套接字通信机制示意图
当应用程序利用Winsock发送和接收数据时,是由核心模式驱动程序AFDSYS负责管理发送和接收缓冲区来发送和接收数据。当应用程序调用send或WSASend函数来发送数据时,AFDSYS在后台负责把数据复制进他自己的发送缓冲区,然后send或WSASend函数立即返回,AFDSYS在后台把数据发送出去,远程客户端接收数据的情况也类似,由接收方的AFDSYS在后台负责把数据复制到自己的接收缓冲区,然后应用程序调用recv或WSARecv函数来接收数据时,把数据由AFDSYS管理的接收缓冲区复制到应用程序提供的缓冲区中。
AFDSYS管理的发送缓冲区SO-SNDBUF和接收缓冲区SO-RECVBUF在缺省时两个缓冲区的大小都为8,192个字节,但可以根据实际要求由应用程序设定,由于我们传输的对象是大数据量文件,因此需要对系统的发送缓冲区和接收缓冲区作相应的设定,以保障大数据量的文件数据的发送的接收。
1.2 问题的分析
1.2.1 通信的模式
由于是实现点对点的文件传输,因此在程序中我们使用的是C/S的模式来实现通信。对于C/S的模式,即分为客户端和服务端。服务端用来接收客户端的连接,实现两端之间互相传输文件。采用C/S的模式可以更好的体现程序的功能设计思想,充分调用在LAN中的server和client两方面的处理能力,极大的减少网络上的信息流通量。C/S体系结构有可能提供一种开放式的、易伸缩扩展的分布式计算机环境,并保护硬件等投资。
1.2.2 传输的可靠性
要想实现文件的可靠性传输,可以使用流式套接字。因为流式套接字提供面向连接的、无差错的、发送顺序一致的、包长度不限和非重复的网络信息的传输,能提供更好的可靠性。而对于数据报套接字提供的是无连接的服务,以的数据报进行传输,不保证顺序性、可靠性和无重复性,相比之下用流式套接字能提供更好的的可靠性传输。
2 程序设计与实现
2.1 程序设计
2.1.1 总体设计
本程序的文件传输系统的实现应包含服务端模块、客户端模块、界面显示模块等几个部分,整个程序采用VC++6.0完成,通信部分采用WINSOCK。程序使用流式套接字,基于C/S模型。在设计GUI界面时把客户端和服务端放在一个界面中,根据用户需要将程序设置成客户端和服务端。服务器和客户机的基本流程如图4所示。
在通信的时候主要可以分为两个部分,一个部分是控制信息的传输部分,而另一个部分就是文件的传输部分。传送的控制信息可以包含发送文件的请求,文件的名称、大小等,由于这方面的数据量比较小,因此采用了MFC所提供的CSocket类的串行化技术来实现。对于文件的传输,由于数据量相对来说比较大,所以用两个线程来实现文件的传输,一个线程用于发送,一个线程用于接收。图5是一个成功的文件传输过程的流程。
否
是
SendMsg
图4 服务器和客户机的基本流程
图5 文件传输过程交互图
2.1.2 模块设计
(1)服务端模块
定义一个服务器端的套接字的类CServerSocket继承于CSocket类,创建一个类CServerSocket的对象,作为程序窗口类CFileTransfersDlg的成员变量。在服务器端建立一个类CServerSocket的对象,来监听客户端的连接。由于采用CSocket类的串行化技术来发送和接收信息,因此创建一个消息类CMessage继承类CObject来封装信息。可用函数Serialize(CArchive& ar)来实现串行化技术。最后用析构函数来结束Socket 连接和释放Socket所占用的资源。
(2)客户端模块
定义一个客户端的套接字的类CClientSocket继承于CSocket类,创建一个类CClientSocket的对象,作为程序窗口类CFileTransfersDlg的成员变量。在客户器端建立一个类CClientSocket的对象,来与服务器建立连接。同服务器端一样使用消息类CMessage封装信息,从而实现消息的接收和发送。可用函数Serialize(CArchive& ar)来实现串行化技术。最后用析构函数来结束Socket 连接和释放Socket所占用的资源。
(3)界面显示模块
面向对象程序设计主要是基于用户事件响应的设计方式。而客户端图形界面(GUI)设计的中心问题是用户控制式。现代面向对象程序是事件驱动的,对象响应事件(消息)。对象之间的内部通信由外部用户激活的事件来触发。友好的界面设计包括以下六点方针,包括用户控制式、一致性、个性化和客户化、宽容、反馈。由于客户端程序与服务器程序很类似,所以就把客户端与服务器端打包在一起,通过按钮选择就可以确定本地主机是客户端还是服务器端了,而且这样也方便了文件的互传,只要安装了此软件,你既可以把本地主机当做服务器向远地主机发送文件,又可以把本地主机当做客户机接受从远地主机发来的文件。本程序的服务器的GUI界面如图6所示,客户机的GUI界面如图7所示。
图6 服务器的GUI界面
图7 客户机的GUI界面
2.2 程序的实现及测试情况
2.2.1 程序的实现
(1)实现步骤
① 建立一个新工程FileTransfers
使用 MFC AppWizard (exe) 建立一个新项目FileTransfers,选择基于对话框的应用,并在向导的第四步中,选择“Windows Socket”选项。
建立所需的文件
程序中所需的文件如下:
头文件:
ClinetSocket.h
ServerSocket.h
Message.h
MyFileTrans.h
MyFileTransDlg.h
Resource.h
Stdafx.h
源文件:
CClinetSocket.cpp
CServerSocket.cpp
Message.cpp
FileTransfers.cpp
MyFileTrans.rc
MyFileTransDlg.cpp
stdafx.cpp
资源文件:
MyFileTrans.ico
MyFileTrans.rc2
(2)程序的使用
运行此软件后,首先要在界面上选择的是套接字类型,是服务器还是客户机。在服务器启动后,客户机中输入服务器的IP地址就可以连接到服务器。当连接成功后,就可以在传送端(服务器/客户机)选择要传输的文件,然后我们就可以在接收端(客户机/服务器)保存此文件。
2.2.2 程序的测试
(1)运行软件,选择套接字类型为服务器,然后点击“启动”按钮开启服务器,监听客户端的连接,如图8。
图8 服务器启动后的界面
(2)在运行软件,选择套接字类型为客户机,然后点击“连接”按钮连接到服务器,建立与服务器的连接,如图9。
图9 客户机启动后的界面
(3)在服务器端点击“选择文件”按钮,在弹出的窗口中选择要传输的文件(也可以在客户机中点击“选择文件”按钮来向服务器传输文件)。服务器端的操作如图10。
图10 服务器选择传输的文件
(3)在图10中点击“打开”后,在客户机中可以看到,如图11的结果。即客户机接收到服务器发来的请求,提示文件要保存的路径。
图11 客户机保存传输的文件
(4)在图11中点击“保存”后,在客户机和服务器中可以看到文件传送和接收的进度,如图12和图13。
图12 文件的传送进度
图13 文件的接收进度
(5)测试结果
比较发送的文件和接收的文件的大小。从图14可以看出,文件的长度和收到的长度大小相等,因此该程序实现了文件的可靠性传输。
图14 文件接收结果
参考文献
[1] 梁敏,陈万军.用于实现基于TCP/IP的局域网内点对点的大文件传输[J].西北民族大 学学报,2005年,26卷(期刊).
[2] 夏靖波,杜华桦,王晓东,段.Windows网络程序设计[M].西安:西安电子科技大学 出版社,2006.
[3].基于Visual C++6.0的点对点文件传输实现[C] . http://wenku.baidu.com/view/e23f441b6bd97f192279e933.html,2010-05-05
参考文献通常应为近3年的,至少5篇,其中最好有英文文献。其具体写法为:
1. 专著、论文集、毕业论文、报告等
[序号]作者.书名[文献类型标志].出版地:出版者,出版年.起止页码(任选).(文献类型标志:专著M;论文集C;报告R;其它文献Z)
2. 期刊
[序号]作者.篇名[J].刊名,年,卷(期刊).
3. 电子文献
[序号]主要责任者.电子文献题名[文献类型/载体类型] .电子文献的出版或可获得地址,发表或更新的期/引用日期(任选).
(文献类型标志:数据库(网上)DB(DB/OL);计算机程序(磁盘)CP(CP/DK);光盘图书M/CD)
附录
程序的源代码
//ClientSocket.h
#if !defined(AFX_CLIENTSOCKET_H__E3382998_1502_46F5_B0EA_C52542E7F4F5__INCLUDED_)
#define AFX_CLIENTSOCKET_H__E3382998_1502_46F5_B0EA_C52542E7F4F5__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "FileTransfersDlg.h"
#include "Message.h"
class CClientSocket : public CSocket
{
public:
CClientSocket();
virtual ~CClientSocket();
public:
CSocketFile* m_pFile;
CArchive* m_pArchiveIn;
CArchive* m_pArchiveOut;
void Init();
void Abort();
BOOL SendMsg(CMessage* pMsg);
void ReceiveMsg(CMessage* pMsg);
CClientSocket(CFileTransfersDlg* pdlgMain);
public:
virtual void OnReceive(int nErrorCode);
protected:
CFileTransfersDlg* m_pdlgMain;
};
#endif
//ServerSocker.h
#if !defined(AFX_LISTENSOCKET_H__9020F185_706C_4AAC_8CDE_DFC8F9DAD490__INCLUDED_)
#define AFX_LISTENSOCKET_H__9020F185_706C_4AAC_8CDE_DFC8F9DAD490__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "MyFileTransDlg.h"
class CServerSocket : public CSocket
{
// Attributes
public:
// Operations
public:
CServerSocket();
virtual ~CServerSocket();
// Overrides
public:
CServerSocket(CFileTransfersDlg* pdlgMain);
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CServerSocket)
public:
virtual void OnAccept(int nErrorCode);
//}}AFX_VIRTUAL
// Generated message map functions
//{{AFX_MSG(CServerSocket)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
// Implementation
protected:
CFileTransfersDlg* m_pdlgMain;
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_LISTENSOCKET_H__9020F185_706C_4AAC_8CDE_DFC8F9DAD490__INCLUDED_)
其它说明:
(1)文档页面设置为:上边距3厘米,下边距2.5厘米,左边距3厘米,右边距2厘米,如下图所示。
(2)文档一律用Word 2000版本以上编辑和排版,激光打印机、A4纸张打印。其中,封面、目录、评审表单面打印,正文双面打印。
(3)文档的装订顺序为:封面、评审表、目录、正文。若文档的最后一面的页码为偶数,则装订时要加装一张白纸。
(4)在Word中插入图片后,不要对图进行长宽方向的非比例缩放。在图上单击右键,在快捷菜单中选择“设置图片格式”命令,打开“设置图片格式”对话框,然后在其中的“大小”选项卡中设置图片高度为70%~80%(根据图片的具体大小确定,一般全屏图设为70%,对话框等其他图可设为80%,使图中文字经缩放后为6号字大小)。
(5)图表编号及章节标题编号不使用Word的自动编号功能。
(6)不要用空格或添加回车键的方式来调整对齐或上下间隔,而应该使用Word自带的段落命令及分隔符等命令来调整。各级标题末尾不要加标点符号。
(7)不出现孤立编号,例如,不出现只有1.4.1而无1.4.2等后续编号的情况。
(8)表示数值范围用“34~56”,不用“34—56”。
(9)对于文档的正文部分,需在页脚部分设置页码,详见本文档中的第5、6页。
