<font color=#FF0000>连发两次SendText的奇怪问题,Socket高手请进.SOS!</font>(200分)

  • 主题发起人 主题发起人 wheel
  • 开始时间 开始时间
W

wheel

Unregistered / Unconfirmed
GUEST, unregistred user!
环境:D5的ServerSocket和ClientSocket+advanced server win2k
比如,在ServerSocketClientRed里写:
Socket.SendText('abc');
Socket.SendText('123');
则ClientSocket只触发一次OnRead,且收到的为('abc123');:((
只要在两次SendText间加一个sleep(1)就不会这样.为什么???
这里是举一个例子,实际情况更复杂.但问题差不多就在这个上。
问题:1.怎么解决?
2.原理何在?
小弟很急,没时间研究控件源码,老大们点拨一下吧.
 
在每次发送的最后加上标记,再在收的时候判断。
 
你忘了么加上传送结束的标记了
sendtext('abc'+#13+#10);
sendtext('123'+#13+#10);
这样socket才知道这是分两次送的数据
 
这在以前讨论过,当时称为沾包什么的,关键是tcp传送的是字节流,
小的ip包的效率不高所以它会尽量用合适的长度
 
Socket可以想象为一个管道,在应用层它是不会给你加界定符号的。你要自己来。
不要认为底层的报文有界定符,那么上层也会有。
你收到abc123还算幸运,你还有可能收到“abc12”和“3”,以及“ab”和“c123”…
你要自已在接收端开一个缓冲区来拼接和截断自已的报文--根据自已定义的界定符。
terry_lzs的回车、换行界定符是最常用的。
 
同意terry_lzs的说法和honestman的建议
 
如果你明白TCP/IP的原理就很easy了,发送和接收没有直接的关系,就象一个管道,你分几次
发送和几次接收没有任何关系,Read从端口的缓冲(OS设定的)读数据,尽量多读,但是缓冲
开始只有3个字节它就返回3个字节,如果有6个字节就返回6个。如果你使用控件就按照上面的
回答解决这个问题。
但是如果你要很精确控制就自己写socket(winsock api),这样就可以精确控制了
 
自已处理数据包,太麻烦了吧!TClientSocket/TServerSocket不是已经处理过了吗?
如果没有估错,wheel的测试应该是在同一部电脑上运行的结果。
有两种方式可收到正确的数据:
1.将ClientSocket与ServerSocket分别放在不同的机器上运行;
2.或者在第一个SendText后加上Application.ProcessMessages或Sleep(1)。
 
多谢各位.
因为实际情况比这复杂,用加#13#10的办法好象不行,我想只能在记录前加字节计数了.

我现在的理解是:
server.sendtext后触发client端onread,因为server是连续发送,所以在client触发onread
时,后一个字符串也已发到,所以从缓冲区读出来的包括后一个字符串。
而在server sleep(1)后,就使client得到足够的时间处理缓冲区数据。
不知对否?
 
不是这么理想,在复杂的网络环境下,你怎么知道server.sleep(1)就够了?万一不够,
server.sleep(1)和什么都不做有什么不同?
加界定符能保证你报文边界的清晰,如果你的实际情况更复杂,能否说得更明白一点。
 
因为我在程序中已经用到了#13#10,而且#$00-#$FF都要使用。加结束标志容易产生歧义。

所以我想用在每个记录前加记录字节计数。应该没什么不妥吧?
 
另外加记录子节数也是防止溢出的方法。
 
加记录字节数的方法可行,我因为要求不严,所以什么都没处理,现在问题就出来了。
 
多人接受答案了。
 
想给答案的,怎么结束了?
 
后退
顶部