您的位置:首页 > 其它

bcb UDP传送文件的一般思路

2011-11-20 18:54 197 查看
在我的资源稍后奉上两种办法实现的源码。

C++ Builder下三种UDP通信实现方法比较

/article/10207578.html

1.利用重发机制(源代码见我的资源TNMUDP实现UDP传文件)

文件传送的基本思路是把文件分成大小适当的数据块,每一次传送一个数据块。每一块数据有一个校验码,接收方根据校验码校验收到的数据块是否正确无误。同时为了能够保证数据块的正确顺序,还要表示数据块的序号。把有关信息组成一个个数据包,通过发送、接收方的正确处理,保证整个文件传输的快速、准确。

一、 数据包结构:

typedef struct

{

char FileFlage[6]; //标志:文件传送类数据包的第一个字节是“F”

unsigned short CRC; //校验码

long Size; //数据长度

long Position; //文件指针

char Data[1000]; //数据区

} TSendFileData;

说明:

1、标志:表示这个数据包的类型(详细说明见后)。

2、校验码:一般情况下,校验码放在整个数据包的最后面。这里把它放在这里的原因是由于数据包的长度不定,操作略有不便,所以放到这里。注意在计算校验码时要先把这个字段清零,然后再计算。至于校验码的形式,建议采用CRC校验方式。我这里是CRC16方式。也可以用其它校验方式。

3、数据长度:指明数据区中实际数据的字节数。

4、文件指针:指明本数据区中的数据块在被传文件中的文件指针位置。(这个字段在不同类型的数据包中有不同的意义,也就是在传送一些特殊数据包时,利用这个字段传输一些特殊的数据(详细说明见后)。

5、数据区:要传送的数据块。数据的大小,要考虑所采用的传输方式的误码率和传输效率。在UDP方式下,资料建议在1024以内,所以这里是1000字节。

二、数据包类型:

全部数据包分为发送方数据和接收方数据两大类,分别以FS和FR开头。

1、发送方指令以FS开头。

a)FSName:数据包内容是要发送的文件名和文件长度。

FileFlag=”FSName”,Size=文件名长度,Position=文件长度,Data=文件名。

b)FSFile:数据包的内容是被传送文件的数据块信息。

FileFlag=”FSFile”,Size=数据块长度,Position=对应文件的指针位置。Data=文件数据块,除最后一块的长度可能小于1000外,其余长度都是1000。

c)FSStop:发送方通知接收方,接收方所要求的数据块已经发送完毕。

FileFlag=”FSStop”,Size=0,Position=无效,Data=无效。

d)FSCanc:发送方通知接收方中断传输。(一般是发送方用户干预,中断传输)。

FileFlag=”FSCanc”,Size=0,Position=无效,Data=无效。

e)FSRepa:发送方收到接收方传来的数据有错误,通知接收方重发。

FileFlag=”FSRepa”,Size=0,Position=无效,Data=无效。

2、接收方指令以FR开头。

a)FRReje:接收方拒绝接收文件。

FileFlag=”FRReje”,Size=0,Position=无效,Data=无效。

b)FRRead:通知发送方按照指定的块号发送文件数据块。块号组成一个整型数组,存放在Data数据区。一般情况下,一次可以发送的块号数量=数据区长度/sizeof(int)=1000/4=250个。

FileFlag=”FRRead”,Size=sizeof(int)*所需数据块数量,Position=无效,Data=数据块号数组。

c)FREnd:通知发送方整个文件传送完毕。

FileFlag=”FREnd”,Size=0,Position=无效,Data=无效。

d)FRRepa:接收方收到的数据有错误,通知发送方重发。

FileFlag=”FRRepa”,Size=0,Position=无效,Data=无效。

e)FRErr:接收方建立或写文件出错,通知发送方。

FileFlag=”FRErr”,Size=0,Position=无效,Data=无效。

f)FRCanc:通知发送方收到中断命令。

FileFlag=”FRCanc”,Size=0,Position=无效,Data=无效。

二、通信流程:

1、发送方发出[FSName]命令。

2、接收方如果拒绝接收文件,则发送[FRReje]。否则按照指定的文件名建立文件。按照文件长度计算要分的文件块数量,按块数量建立一个块号数组,用来表示已经接收到的文件块。

3、接收方搜索块号数组中未收到的块号,把它组成一个要发送的块号数据,用[FRRead]命令把这个块号数据发发给发送方。

4、发送方按照块号数据读取文件,并发送每一个数据块[FSFile]。

5、接收方把正确收到的数据块按块号写入文件,并把相应的块号数组元素置成已接收。

6、循环执行4-5。

7、当发送方把块号数据中要求的数据块全部发送完毕后,发出[FSStop]命令,通知接收方指定的块号已经发送完毕。

8、循环执行3-7。

9、如果接收方搜索块号数组中已经没有未接收的数据块,则发送[FREnd]通知发送方文件已经全部传送完毕。

10、如果在传送过程中,发送方要强行中断传送,则发出[FSCanc]命令。接收方中断文件接收,并回应[FRCanc]。

11、如果接收方在建立或写文件中出错,发送[FRErr]通知发送方文件错误。

12、如果收到的数据包(不论是发送方还是接收方)发生校验错误,则用[FSRepa]或[FRRepa]通知对方重发最后一个数据包。

三、几点说明:

1、由于通信过程中不可避免地会出现错误,因此需要对收到的数据包进行校验。如果正确,则通知对方继续发下一个数据包,如果错误,则通知对方重发当前数据包。

2、如果对方在制定的时间内没有返回回应,则说明丢失了数据包,发出数据包的一方应当主动重发最后一个数据包。

3、但是这种一来一往的通信方式,大大降低了通信速度。为了能够尽量提高速度,同时又保证数据的准确完整。对于除[FSFile]以外的命令按照如上这种一来一往的方式来保证数据传送的准确可靠。

4、对整个文件传送过送过程中使用最多的[FSFile]命令,采取不进行应答方式的传送。发送方只管把所需要的数据块连续发出去,而不管接收方是否正确接收。而接收方根据块号数组清除地掌握着还需要重新传送那些块号的数据块。每发一次[FRRead]命令可以包含250个所需块号,而发送方就要发送250个[FSFile]。实践证明,这种方式的文件传送速度很快,而且很可靠。

2.:利用通讯机制

对方收到包后立即回发对方一信息表示自己收到,然后发送方再发送下一个包,此法效率低,但实现起来很简单

详细实现过程稍后附上代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: