高分求解INDY10网络通讯问题,熟悉INDY10的高手请进 ( 积分: 200 )

  • 主题发起人 主题发起人 小城有我
  • 开始时间 开始时间

小城有我

Unregistered / Unconfirmed
GUEST, unregistred user!
用INDY10的TIdTCPServer做通讯服务端程序,客户端为硬件设备,请问服务端如何读取客户端数据?

我已进行了如下测试:
1. 在IdTCPServer的 OnExecute中读取,发现只有以$0A结束时才触发OnExecute事件,而且$0A不能读到,但我的下位机数据不确定,所以不能使用此方法

2. 另开一线程,用ReadBytes方式查询读取,但又碰到了一些问题,一是超时问题,一旦读取超时就报错,只好用 try..except,但调试时频频报错,很是不爽,最主要的是第二个问题,在调试时发现有些时候数据不能及时读到,例如:客户发送了一个字节比如 $AA ,ReadBytes读取不到,只有客户再发送了一个字节比如 $BB,这时ReadBytes 才将两个字节 $AA,$BB 一起读出,经过反复测试,偶尔会出现这种情况,不知是什么问题,该如何解决,另外我用ReadChar,ReadStream等方法读取测试,也会出现同样的问题,难道是INDY10的BUG?

请各位高手提供一个好的解决,不盛感激!
 
不要用WriteLn发,不要用 ReadLn 读,就没事了。
 
indy10没怎么用过,据说比以前版本改动很大,tcpserver使用了iocp(完成端口)模式,这里有篇indy10做端口映射的代码,应该对楼主有参考价值,可以看看:
http://hi.baidu.com/rarnu/blog/item/f88db53564b6988ba61e129b.html
 
to 白河愁,
 
to 白河愁,你可能没看清我的问题,我用的是readbytes和readstream,都不行啊
to ufo,这篇文件我看过,不过跟我的问题好像关系不大
 
OnExecute是在线程对象中用
while not .... do
begin
....
OnExecute;
end;
这样循环调用的,只要连接没断开,这个循环就一直存在。你可以在onExecute下写任何读写代码,都没有问题的。不过,注意,在ReadBytes和ReadStream的调用过程中,Indy有自己的读写规范(这个可能和你的硬件设备发送方式不一样),你可以详细阅读一下上述两个方法的源码(在TIdIOHandler的子类TIdIOHandlerStack中),这两个方法在通讯的时候如果不指定长度,会首先发一个长度数据过来,然后再读取实体数据。你可以检查一下你的硬件设备有何种发送规则,自己继承个TIdIOHandler实现通讯即可。
 
另外,Indy的几乎所有Server控件,本身就是多线程的。你不必要自己再创建个线程去做什么处理。因为具体处理Indy都帮你完成了。
 
2. 另开一线程,用ReadBytes方式查询读取,但又碰到了一些问题,一是超时问题,一旦读取超时就报错,只好用 try..except,但调试时频频报错,很是不爽,最主要的是第二个问题,在调试时发现有些时候数据不能及时读到,例如:客户发送了一个字节比如 $AA ,ReadBytes读取不到,只有客户再发送了一个字节比如 $BB,这时ReadBytes 才将两个字节 $AA,$BB 一起读出,经过反复测试,偶尔会出现这种情况,不知是什么问题,该如何解决,另外我用ReadChar,ReadStream等方法读取测试,也会出现同样的问题,难道是INDY10的BUG?

至于你的这个问题,请阅读一下IdBuffer类的相关代码,Indy自己有缓冲区,首先会缓冲你的数据,然后才会发给具体的ReadBytes和ReadStream,至于你提到的ReadChar的问题,貌似不会啊。不过我没你的测试环境,不太了解是不是有什么特殊原因。不过有一点我可以告诉你,所有Delphi自带的Indy10(从D7-D2007),全部用的是Indy团队发布的10.0.15这个版本,这个版本实际上有很多bug,其中有关键的IOHandler读写上的Bug,导致许多Indy控件在数据读取上都有问题,建议你去下载Indy DevSnapshot版本来安装使用,这个版本我曾经发布到www.2ccc.com上了,你去这里下载:
http://www.2ccc.com/article.asp?articleid=4100
 
to ufo!
Indy10的SupperCore是完成端口的。。。。可是负责写这部分的人几乎有1年多没碰这个部分了,导致Snapshot版本中,这个部分已经无法直接通过编译而使用,而是需要人工修改。。。。实在是郁闷。
 
感谢zqw0117的解答,按照你的说法我先试试.
 
indy10的tcp组件没用过,只用indy10的udpserver组件写了个通讯模块(供mrp系统内部使用)主要是indy10之前的版本udp组件有个毛病,当发一个数据到一个不存在的ip时,会引发一个异常,然后组件就再也接收不到数据了。

至于楼主提到只是偶尔收不到数据,我想这个偶尔是否有规律(比如在收发了多少数据后才出现),客户端的硬件设备是否经过严格测试,保证是成熟产品?
 
处理BYTE数据的话,INDY还是少用为妙吧,自己直接用API写个就行了,或者用ICS也方便些,INDY的服务端长连接的话不稳定。
 
按照zqw0117,我安装了Indy DevSnapshot之后,感觉好用多了,但现在有个问题,就是在我访问Contexts的Data属性时,LockList列表时就会进入死锁状态,UnlockList不能解锁,怎么办啊?请指点
我的代码如下:
procedure TRead.Execute;
var
CurrentOpNo:integer;
ClientInfo:TClientInfo;
begin
CurrentOpNo := 0;
while not self.Terminated do
begin
ClientInfo := nil;
try
mConnectNum := FidServer.IdTCPServer1.Contexts.LockList.Count;
if mConnectNum > 0 then
ClientInfo := TClientInfo(TIdContext(FIdServer.IdTCPServer1.Contexts.LockList.Items[CurrentOpNo]).Data);
except
end;
if ClientInfo <> nil then
begin
... ...
end;
FIdServer.IdTCPServer1.Contexts.UnlockList;
Application.ProcessMessages;
sleep(500);
end;
end;
 
locklist与unlocklist需要一一对应,否则很容易造成死锁现象,将代码作如下修改即可
try
mConnectNum := FidServer.IdTCPServer1.Contexts.LockList.Count;
FIdServer.IdTCPServer1.Contexts.UnlockList;
if mConnectNum > 0 then
begin
ClientInfo := TClientInfo(TIdContext(FIdServer.IdTCPServer1.Contexts.LockList.Items[CurrentOpNo]).Data);
FIdServer.IdTCPServer1.Contexts.UnlockList;
end;
except
end;
 
谢谢,正在测试中
 
谢谢 wym126
请问INDY10的IdTCPServer如何停止服务才不报错,我尝试断开所有连接再将IDTCPSERVER.ACTIVE := FALSE; 可经常报错,停止不了.
 
下载地址:http://2008pq.com/news/index.asp
联系QQ:147858017
P2P即时通讯聊天软件全部源码,无加密,组件齐全,调试非常简单方便!
发送联机或脱机消息,同时可自定义消息字体、颜色、大小等信息,支持插入表情符号,屏幕截取。
支持多人消息群发等功能;在线即时语音、视频聊天;
穿透网关防火墙,可在互联网和局域网任意对话;
系统采用先进的点对点通讯技术,消息(包括文本、语音、视频、文件)的
传输大多数情况不需要经服务器中转而直接发往接收者所使用的机器,传输速度更快。
而且因服务器仅仅只是起着维护用户状态列表的功能,因此占用资源极少,
可允许同时在线的人数就越多,对系统的影响也最小。
可以设置各种离线状态,支持自定义状态;

提供各种源代码:(asp,delphi,vb,vc++,java,等)

商品进销存管理系统
图书信息管理系统
学生成绩管理系统
订单管理系统
教务信息管理系统
仓库管理系统
工资管理系统
档案管理系统
考勤管理系统
客户信息管理系统


联系QQ:147858017
 
回答完最后一个问题就放分了,请问INDY10的IdTCPServer如何停止服务才不报错,我查找好多贴子,试了好多方法,都没有解决,请高手指点.我用INDY10+DELPHI7。
 
底层通讯最好用C写, 平台移植性也好, 有问题也好跟踪, 用别人的东东就是这样了。

你的问题想不报错都难, 要想停止服务, 干脆使用葵花宝典, 挥刀自宫, 使用exitprocess干了自己, 再用另一监控程序重新启动程序。 嘻嘻!
 
我现在就是用 TerminateProcess 自杀,但老感觉不是很妥,且不能在程序中停止服务.
难道 Indy 真的不能用吗?
 
后退
顶部