轮子学习笔记二:关于Delphi中NMUDP的Bug(100分)

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

wheel

Unregistered / Unconfirmed
GUEST, unregistred user!
这段时间很颓废,没有在无聊中恋爱,眼看着要在无聊中变态了,帖点东西出来让大家们骂.

轮子学习笔记二:关于Delphi中NMUDP的Bug

1,众所周知,TNMUDP最明显的一个Bug是当在程序创建一个TNMUDP类的实例后,会导致操作系统无法正常关闭.
解决方法:
在主窗口的OnClose或OnCloseQuery中释放所有的TNMUDP类实例,如:NMUDP1.Free;

2.当使用TNMUDP发送数据时,如果目标IP能够解析,而目标端口无法接收数据时,将会倒致发送数据的NMUDP控件触发一次
OnDataReceive事件,并且NumberByte=-1.如果不处理这个问题,往往会造成程序的Bug.
这也是众多兄弟所问的用NMUDP时为什么会出现ReadBuffer所收到的数据为乱码或在
OnDataReceive中出现write stram error 的原因.
解决方法:
在OnDataReceive事件中的添加:if NumberBytes=-1 then Exit;

3.SendBuffer,ReadBuffer.(不是Bug的Bug?).
或许很多人曾经试图象我一样用SendBuffer(PChar(Str)^,Length(Str)的方法来发送数据,在TClientSocket.Socket.SendBuf中
你可以这样用,但在TNMUDP.SendBuffer中是不行的.虽然编译允许你这样用,但实际上SendBuffer的Buff参数被声明为array of Char.
当使用PChar(Str)^当做Char数组来用时,传过去的Char数组仅仅只包含一个字符,相当于一个Char.
不知道TNMUDP为什么会发送前四个正确字符,而以后的为乱码?估计是因为默认情况下String类型为AnsiString,
而AniString的最始情况占用内存数为4bytes.

另一个令我困惑的是,在NMUDP控件的Help中有一段代码如下:
procedure TForm1.NMUDP1DataReceived(Sender: TComponent; NumberBytes: Integer; FromIP: String; Port: Integer);
var
C: array [1..3] of Char;
I: Integer;
begin
if NumberBytes <= 3 then
begin
NMUDP1.ReadBuffer(C, I);
Memo1.Lines.Add(C+': received '+IntToStr(I)+' bytes from '+FromIP+' on port '+IntToStr(Port));
end
else
Memo1.Lines.Add(IntToStr(I)+' bytes incoming, buffer too small');
end;

这里这个I用得莫名其妙,怎么看这段代码都不通.
而NMUDP的ReadBuffer的Length参数也令人迷惑,无论你传一个值为多少的变量,它都会正确读取接收到的数据
并将Length变量置为正确的长度,这和Help的介绍是不一致,而且实在想不到这样做的道理。:(

最后结论,还是不用NMUDP控件了吧,好在Delphi6中提供了Indy.:)

暂定写到这里吧,欢迎兄弟们指正,讨论。:P

Email:redware@21cn.com

轮子

2001.9.25
 
谢谢了,我试试看
 
的确,在Delphi中的确出现这样的问题,我用两个客户端执行一万次循环对一个服务器进行发送消息,
结果使用TNMUD控件时发生严重丢包现象,前面和后面的好一点,丢的最惨重的是中间发送的数据包,
为此我采用Delphi6写,使用其中的Indy控件,结果发现它稳定多了,没有发生丢包现象,而且效率高
多了,其中的实例可以参考Delphi目录下的Demos下的实例,在此不写出来!
 
发送数据最好用sendstream.
如果你用sendstream试的话,丢包的情况就好多了.
 
在www.51delphi.com上有个升级。
http://www.51delphi.com/fenlei.asp?type=TCP/IP
 
谢谢
请 轮子 大侠继续贴,学习学习,期待中。。。
要分您说话[:D]
 
多人接受答案了。
 
后退
顶部