不能完整接收sockets数据包,如何解决? (200分)

  • 主题发起人 主题发起人 totogirl
  • 开始时间 开始时间
T

totogirl

Unregistered / Unconfirmed
GUEST, unregistred user!
我用的是静态数组,
var
Bufferread:array[0..60000] of byte;
Stream:TWinSocketStream;
.....
begin
.....
while ClientSocket1.Active do
begin
Try
Stream:=TWinSocketStream.Create(ClientSocket1.Socket,60000);
try
FillChar(Bufferread,60000,0);
........
If Stream.WaitForData(20000) then
begin
If Stream.Read(Bufferread,60000)=0 then
begin
ClientSocket1.Close;
end;
但是,这之后大概从Bufferread[3760]开始,以后都是空值了,
而Bufferread[3760]之前的数据都正确,why???
我试着调整了Bufferread:array[0..60000] of byte;的大小,错误一点都没变,
试着调整了Stream.WaitForData(20000) 的时间值也不行,
如果用动态数组,那么初始化时 FillChar(Bufferread,60000,0);是不是会出错??
我的程序错哪了??
另外,Bufferread[3760]之后肯定是有数据的,可收不到.
但对方过来的第一个数据包是10000byte左右.


 
呵呵,你先说说服务端是怎么发数据的吧。
 
分包发,每个包9999byte,最多6个包,
因为我现在是第一个包接受就不完整,所以大概和接受后续包无关.
另外,Bufferread[3760]之前接收的数据是完全正确的.
 
把服务端的代码贴贴吧,只要2端BUFFER大小一致应该是没啥问题的。
查查以前的帖子吧,很多这方面的内容很多的
 
服务器是别人写的,我没有代码.[:(]
以前的帖子没有查到.
帮一下,谢谢
我的数组???有没有问题??
 
不知道服务端的如何发送的,
因为分包发,每个包9999byte,最多6个包,所以一般来说是用STREAM发送的,我觉得你首先弄清他发送的格式比较重要,一般会在传输数据前先发一些标志,各数据分段也会有特殊符号标记的。接收后再解析放到数组里就行了。
 
你用的是serversocket和clientsocket的阻塞模式
你说的问题有两个方面原因:
1、和组件的默认缓冲属性有关,这两个组件的值为8192。
2、和发送和接收代码有关系。就是你刚刚说的那个20000的值有关系。
如果你不介意,可把代码贴出来,或者发到我的信箱,我帮你看看。
jiajiajia888@sohu.com.
 
白天不能上网,现在才能看到各位的回答.
>>vefar
1.的确就是 Stream.
2.正如我上面的帖子所言,我就是往数组里放的,
3.Bufferread[3760]之前接收的数据是完全正确的.
也就是说完全符合发送的规格,要求,和预期的一样.
>>jiajiajia888
和组件的默认缓冲属性有关,这两个组件的值为8192
1.在那里可以看到这个属性"8192"?可以修改吗?
2.不是不愿意贴代码,现在我只是试着做了一个临时程序,
我想成功后再往其他程序里写,现在这个临时程序和接收相关的基本上就是
上面贴出的那些了,其他只是把数据导入一个memo,还有就是发包,
发包肯定是正确的,要不会返回提示错误的数据包.
 
一次收不全是很正常的事的,需要都收几次。socket每次能够发送和接收的包的大小与网络
质量有关系,如果一次收不全所有的包,则需要一直收取,并把各个包相加起来处理。
 
>>chenxz
根据现在的情况判断,您说的这种情况可能性最大,
想请教您:
1.既然是多包发送,会不会出现这种情况,即根据接口协议,一个包是9999大,现在要
把这个大包分成一个个小包来发,那么收到的一个小包会不会既包含前一个大包的
结尾,又包含后一个大包的开始?
2.这些分开的小包的大小是随机的,还是人为确定的?
谢谢
 
tcp/ip协议的socket的简单工作流程是这样的,发送端发送数据到tcp/ip的底层缓冲(缓冲
的大小与操作系统有关),如果缓冲满了(就是发比收快的情况)后,发送端应该是发送失
败(一般是发送超时),接收端从缓冲区里读取数据,发送和读取的量是有tcp/ip协议来
决定的,但对于tcp/ip协议来说,是能够保证数据按先后顺序发送和接收的,并且保证不会
丢包(发送错误的情况除外)。所以一般常连的tcp/ip socket在交互方面一般都需要定义
数据的开始和结束标志,以便在分析数据时能够保证数据的正确完整性。在接收端,一定需
要把所有的数据加起来,然后从接收的数据里找到开始和结束标志进行处理。
 
8192是默认的,除非改组件,是没有办法修改直接改属性的,除非你改组件代码。
:)
你用的是阻塞模式,不用担心分包的顺序。
既然你能够把程序改好,我也就放心了。
 
你在收的前面加上sleep(10)的延时,试一下,我用缓冲区收数据也是收不完,就加个延时就没问题了,我就不知道是什么原因,我到现在都感到奇怪
 
谢谢各位的帮助,问题已经解决.
chenxz说的是问题产生的原因,反复读即可收到后面的数据.

>>在接收端,一定需要把所有的数据加起来,
然后从接收的数据里找到开始和结束标志进行处理。

天那,我几乎花了一天的时间,才理清里面的顺序,

再次感谢各位.

 
牛逼,老子反复读都是一个结果!

3760个字节! 再多就收不到了!
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部