基于socket的文件传输软件的设计与实现Word格式.docx

上传人:b****5 文档编号:21700841 上传时间:2023-01-31 格式:DOCX 页数:14 大小:234.46KB
下载 相关 举报
基于socket的文件传输软件的设计与实现Word格式.docx_第1页
第1页 / 共14页
基于socket的文件传输软件的设计与实现Word格式.docx_第2页
第2页 / 共14页
基于socket的文件传输软件的设计与实现Word格式.docx_第3页
第3页 / 共14页
基于socket的文件传输软件的设计与实现Word格式.docx_第4页
第4页 / 共14页
基于socket的文件传输软件的设计与实现Word格式.docx_第5页
第5页 / 共14页
点击查看更多>>
下载资源
资源描述

基于socket的文件传输软件的设计与实现Word格式.docx

《基于socket的文件传输软件的设计与实现Word格式.docx》由会员分享,可在线阅读,更多相关《基于socket的文件传输软件的设计与实现Word格式.docx(14页珍藏版)》请在冰豆网上搜索。

基于socket的文件传输软件的设计与实现Word格式.docx

图一TCP/IP体系结构

Socket通常也称作"

套接字"

,用于描述IP地址和端口,是一个通信链的句柄。

应用程序通常通过"

向网络发出请求或者应答网络请求。

Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,程序员可以用它们来开发TCP/IP网络上的应用程序。

尽管TCP/IP协议的名称中只有TCP这个协议名,但是在TCP/IP的传输层同时存在TCP和UDP两个协议。

TCP是一种面向连接的保证可靠传输的协议。

通过TCP协议传输,得到的是一个顺序的无差错的数据流。

发送方和接收方的成对的两个socket之间必须建立连接,以便在TCP协议的基础上进行通信,当一个socket(通常都是serversocket)等待建立连接时,另一个socket可以要求进行连接,一旦这两个socket连接起来,它们就可以进行双向数据传输,双方都可以进行发送或接收操作。

UDP是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性都是不能被保证的。

本文在Scoket原理基础上,基于.NET平台,利用线程池技术,设计并实现了分别面向TCP和UDP的可靠文件传输软件。

2.系统体系结构

根据采用的协议不同,本软件分为基于TCP文件传输和基于UDP的可靠文件传输。

在TCP/IP网络中两个进程间的相互作用的主机模式是C/S。

在操作过程中采取的是主动请示方式:

首先服务器方要先启动,并根据请示提供相应服务:

1、打开一通信通道并告知本地主机,它在某一个公认地址上接收客户请求;

2、等待客户请求到达该端口;

3、接收到重复服务请求,处理该请求并发送应答信号;

4、返回第2步,等待另一客户请求;

5、关闭服务器。

客户端:

1、打开一通信通道,并连接到服务器所在主机的特定端口;

2、向服务器发送服务请求报文,等待并接收应答;

继续提出请求……

3、请求结束后关闭通信通道并终止。

2.1面向TCP系统调用时序图

图二面向TCP的系统时序图

2.2面向UDP系统调用时序图

图三面向UDP的系统时序图

3.功能实现

3.1公共类设计

软件设计时,TCP和UDP的服务器端为统一界面,客户端为统一界面。

即服务器端既能够接受TCP连接,也能通过UDP进行接收;

客户端可以通过TCP和UDP进行传输。

3.1.1IP地址操作类

1、IPAddress类

在该类中有一个 

Parse()方法,可以把点分的十进制IP表示转化IPAddress类,方法如下:

IPAddressaddress=IPAddress.Parse(“192.168.100.39”);

IPAddress提供4个只读字段

Any 

用于代表本地系统可用的任何IP地址

Broadcase用于代表本地网络的IP广播地址

Loopback用于代表系统的回送地址 

None用于代表系统上没有网络接口

其中IPAddress.Any最常用可以用来表示本机上所有的IP地址,这对于socket服务进行侦听时便使用,不用对每个IP进行侦听了。

2、IPEndPoint类

通过二种构造方法来创建IPEndPoint类:

a、IPEndPoint(longaddress,intport)

b、IPEndPoint(IPAddressaddress,intport)

它有四个属性:

Address

AddressFamily

Port

MaxPort

MinPort

IPEndPoint是一个IP地址和端口的绑定,可以代表一个服务,用来Socket通讯。

3.1.2DNS相关类

DNS类有四个静态方法,来获取主机DNS相关信息:

1、GetHostName() 

通过Dns.GetHostName()可以获得本地计算机的主机名

2、GetHostByName()

根据主机名称,返回一个IPHostEntry对象:

IPHostEntryGetHostByName(stringhostName)。

其中IPHostEntry把一个

DNS主机名与一个别名和IP地址的数组相关联,包含三个属性:

AddressList:

一个IPAddress对象的数组

Aliases:

一个字符串对象数组

HostName:

一个用于主机名的字符串对象

3、GetHostByAddress()

类似于GetHostByName(),只不过这里的参数是IP地址,而不是主机名,也返回一个IPHostEntry对象。

IPHostEntryGetHostByAddress(IPAddressaddress)

IPHostEntryGetHostByAddress(stringaddress)

4、Resolve()

当不知道输入的远程主机的地址是哪种格式时(主机名或IP地址),用以上的二种方法来实现,可能还要通过判断客户输入的格式,才能正确使用,但Dns类提供一更简单的方法Resolve(),该方法可以接受或者是主机名格式或者是IP地址格式的任何一种地址,并返回IPHostEntry对象。

3.2TCP文件传输

3.2.1服务器端

1、创建IPEndPoint实例,用于Socket侦听时绑定:

IPEndPoint 

ipep 

new 

IPEndPoint(IPAddress.Any, 

7000);

2、创建套接字实例:

serverSocket 

Socket(AddressFamily.InterNetwork, 

SocketType.Stream, 

ProtocolType.Tcp);

这里创建的时候用ProtocolType.Tcp,表示建立一个面向连接(TCP)的Socket。

3、将所创建的套接字与IPEndPoint绑定:

serverSocket.Bind(ipep)。

4、设置套接字为收听模式:

serverSocket.Listen(10)。

5、在套接字上接收接入的连接

在此使用.net的线程池类,默认情况下创建25个线程。

从线城池中获取一个线程来处理客户端请求。

ThreadPool.QueueUserWorkItem。

6、在套接字上接受客户端发送的信息

部分代码:

BinaryReaderreader=newBinaryReader(client.GetStream());

stringfilename=reader.ReadString();

longtotal=reader.ReadInt64();

stringsaveAs=GetSaveFile(filename);

FileStreamfs=File.Create(saveAs);

try

{

byte[]buffer=newbyte[8192];

intlen;

while(total>

0)

len=reader.Read(buffer,0,8192);

if(len==0)

thrownewIOException("

发送方中止了连接"

);

fs.Write(buffer,0,len);

}

3.2.2客户端

1、创建IPEndPoint实例和套接字;

2、将套接字连接到远程服务器;

clientSocket.Connect(ipep)

3、发送信息

FileInfofi=newFileInfo(textBox1.Text);

writer.Write(fi.Name);

writer.Write(fi.Length);

FileStreamfs=fi.OpenRead();

longtotal=fi.Length;

byte[]buffer=newbyte[8192];

while((len=fs.Read(buffer,0,8192))!

=0)

writer.Write(buffer,0,len);

客户端使用openFileDialog类选择文件,然后向服务器端传送文件长度和文件名,最后将需要传送的文件切割成以单位为8k的数据块进行传送。

服务器端使用SaveFileDialog类选择存储文件的位置,然后接受客户端发送的文件名和文件长度,然后进行小数据块接受,使用循环,直至客户端发送完毕,服务器端在接受客户端连接请求时开辟了一个内存池。

面向连接的程序流程图如下所示:

图四面向TCP的程序流程图

3.3UDP文件传输

TCP是面向连接的,所以用TCP传输文件不会丢包。

UDP是非面向连接的,所以UDP是不可靠的,用它传输文件,要保证不丢包,就需要额外代码来保障。

本文采用的是在接受文件端来检测,当开始接收文件,收到一个数据包后,如果等待超过了一定时间后都没有收到数据包,就给发送方发送一个新的请求,要求继续发送文件,直到文件全部接收完成。

流程图如下:

图五UDP传输流程

3.3.1服务器端

在UDP服务器端设计过程中,部分步骤和实现代码与TCP相似,在此不再赘述。

基本的实现步骤:

1、创建一个socket,用函数socket();

2、绑定IP地址、端口等信息到socket上,用函数bind();

3、循环接收数据,用函数recvfrom();

4、关闭网络连接;

为了实现UDP的可靠传输,设计了ReceiveFileManager类,如下图所示:

图六ReceiveFileManager类

可靠传输的具体做法是:

1、在ReceiveFileManager类中加入一个记录文件分块接收状态的列表Dictionary<

int,bool>

,int表示文件分块的序号,bool表示是否已经接收,初始化为全部没有接受(false)。

2、在ReceiveFileManager类中加入一个Timer,用来检测收到一个包后等待的时间是否超过了设置的值,超过就给发送方发送数据包,请求继续发送文件,需要发送的文件块序号为从Dictionary<

中查询出来的没有接收的文件块序号。

3、如果Dictionary<

中的所有文件块已经收到(全部为true),文件就接收完成了。

3.3.2客户端

在UDP客户端设计过程中,部分步骤和实现代码与TCP相似,在此不再赘述。

3、设置对方的IP地址和端口等属性;

4、发送数据,用函数sendto();

5、关闭网络连接;

为了保证UDP的可靠传输,客户端也需要对服务器端某个端口的发送来的信息进行监控,一旦服务器请求,则进行重传。

IPEndPointremoteIP=newIPEndPoint(IPAddress.Any,0);

byte[]buffer=null;

buffer=UdpClient.EndReceive(result,refremoteIP);

catch(SocketExceptionex)

throwex;

finally

ReceiveInternal();

OnReceiveData(newReceiveDataEventArgs(buffer,remoteIP));

3.4线程池

通过System.Threading名称空间的ThreadPool类来使用线程池,它所有的成员都是静态的,而且没有公开的构造函数。

这个限制的目的是为了把所有的异步编程技术都集中到同一个池中。

假如构造了含有两个线程的线程池,当三个请求到达时,它们立刻安排到队列等待被处理,因为两个线程都是空闲的,所以头两个请求开始执行。

当其中任何一个请求处理结束后,空闲的线程就会去提取第三个请求并处理之。

在这种场景中,系统不需要为每个请求创建和销毁线程。

线程之间能互相利用。

而且如果线程池的执行高效的话,它能增加或删除线程以获得最优的性能。

例如当线程池在执行两个请求时,而CPU的利用率才达到50%,这表明执行请求正等待某个事件或者正在做某种I/O操作。

线程池可以发现这种情况,并增加线程的数量以使系统能在同一时间处理更多的请求。

相反的,如果CPU利用率达到100%,线程池可以减少线程的数量以获得更多的CPU时间,而不要浪费在上下文切换上面。

3.5其它

在UDP传输设计中,为了使其界面与TCP传输相区别,调用了网上的通用组件TraFransfersFileControl。

使其更美观。

另外还调用了MD5动态库进行加解密。

4.试验结果

由于实验环境有限,服务器端和客户端均在本机上运行。

传输速度为5M/s。

其界面如下所示:

图七客户端主界面和分界面

图八服务器端界面

图九运行界面

5.思考

1、进行UDP可靠传输,除了上文用到的从接收方检测的方法,也可以从发送方来处理这个问题,就是发送方发送一个包后,如果等待了一定时间没有接收到接受方的回复,就重发这个包。

2、使用了MD5类,传输小文件时没有影响,但是大文件时则问题比较明显,速度比较缓慢。

6.结论和收获

在此之前没有接触过socket,原来在单位解决关于异构系统下通讯的问题时,均采用dropbox(投递箱)机制,或者通过Weblogic。

有时为了解决一个简单的通讯,需要额外的编程量和中间件,所以通过这门课,我感觉有了比较大的收获。

报告评语

教师签字:

日期:

成绩

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 其它课程

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1