高手请进:ClientSocket,ServerSocket传送文件问题(175分)

  • 主题发起人 powersite
  • 开始时间
P

powersite

Unregistered / Unconfirmed
GUEST, unregistred user!
代码:
用ClientSocket,ServerSocket传送文件一个9K文件,两端用SendBuf,ReceiveBuf,而且发送端设置Buff=8192,每次发送时,经检测发现每一小块的确已经完全发送出后,再发送第二个Buff块。发送文件大小正常。但接收方发现,接收第二个块时,接收到的数目要比应该接收的长度长几十个字节。我看来看去没什么地方不妥,真是急疯了!请教是否每一次ReceiveBuf后,SOCK接收的缓冲区应该自动清空?还是别的什么原因呢?急!望高手们急救,不胜感激!小弟还只有175分,悉数奉上!
 
对于发送而言,函数成功返回只是表示你的数据已经进入系统缓冲区。什么时候发送,发送
多少全由系统决定。也许你发送多次系统只发送一次,你发送一次大数据系统要发送多次。
接收的情况也非常类似。所以你不能假定发送和接收的次数和长度是一一对应的。
我的解决方法是,自定义一个发送头填入必要的信息如文件的长度。假如对方在规定的
时间内收到了发送方指定的长度则成功,反之可要求重发。
 
基本同意楼上, 不过我不同意他的发送方式,你完全可以在接受的时候再分包,不要加什么
必要信息,
 
to 张无忌:
好久不见了。
>>你完全可以在接受的时候再分包
什么意思?
如果不加发送头,怎样保证接收数据的完整性?
 
TCP本身就有保证数据完整性 的功能,
 
>>TCP本身就有保证数据完整性
TCP只保证它所携带的数据的完整性。如果发送一个9K的文件,发送函数几乎是立刻
返回。如果系统底层发送完4K后,网络中断,你的程序要等待一段时间才能收到错误
信息。然后决定是否重发。
对于接收方来说,他并不知道他所收的4K数据是不是一个完整的文件。即使他收到了
完整的9K数据,接收方也不知道9K数据是不是一个完整的文件。
 
一般在发送文件的时候开始就把文件的大小告诉了对方, 就可以避免你说的问题
你每个包都有文件大小,处理起来麻烦,而且效率低
 
你误会我的意思了,并不是每个包都有文件大小。准确的说是一个完整的自定义数据块前
加发送头。
 
恩,我知道你的意思,但是这样处理起来很麻烦,我一般是用一个固定的大小的
包,比如说1K就是一个结构,不足的地方用0填充
 
我的情况跟你不一样,我有时候数据很少,只有一个发送头(包含错误信息)。
有时候数据很大(几兆),也只有一个发送头。
 
这可以用一个简单的协议来做,一问一答,可以避免这个问题
 
我觉得一问一答反而增加代码量。我做了两个函数。一个加发送头。一个分析发送头。
这两个函数client和server公用
 
:)可能是我们用的地方不一样,处理方法就不同了
 
同意,就看powersite怎么用了
 
非常感谢张教主的再一次支持,后来我也考虑采用了mywyn的方式。
至于我提到的接收块大于预期大小,后来我发现原本我这样:
Size:=socket.ReceiveLength;
Socket.ReceiveBuf(Buff,Size);
然后将数量为Size的BYTE写入文件中。
后来发现,原来Size:=socket.ReceiveLength中得到的SIZE并不准确,Size:=Socket.ReceiveBuf(Buff,BUFFLENGTH);这样取到的SIZE才是真正的缓冲区接收大小,后来这样:
Size:=Socket.ReceiveBuf(Buff,BUFFLENGTH);//BUFFLENGTH设置得足够大,似乎只要大于8192便足够
再将该SIZE数目的BYTE写入文件中,便正常了。
非常感谢二位,现在我又遇到一个问题,提问到:http://www.delphibbs.com/delphibbs/dispq.asp?lid=1296165
呵呵,请二位多多赐教,小弟感激不尽!
 
顶部