我已经写过一个这样的东西,但是不好用常常出现问题,而且出现的问题比较严重的是会不能采集数据。
我采用的是windows的服务形式编写的程序。出现的错误不外乎两类
1.事件 ID ( 0 )的描述(在资源( MyServer.exe )中)无法找到。本地计算机可能没有必要的注册信息或消息 DLL 文件来从远端计算机显示消息。部分事件包含了下列信息: List index out of bounds (27).
2.事件 ID ( 0 )的描述(在资源( MyServer.exe )中)无法找到。本地计算机可能没有必要的注册信息或消息 DLL 文件来从远端计算机显示消息。部分事件包含了下列信息: Access violation at address 00403D71 in module 'BGServer.exe'. Read of address 01004338.
出第一个的时候还可以正常工作,第二个好像不行了像崩溃了似的。我的软件的要求是通过IdTcpServer作服务器端
在程序启动的时候有一个设备列表
当有设备连接服务器的时候通过查询列表
知道那个终端连接的
最后就是数据链路维护,当发现30秒连接的客户端没有数据强制断开连接
不知道那个高人有这样的构架,让小弟了解了解我的方式是仿照了delphi的例子作的
Clients:Tlist来维护连接
但就是这个clients出问题
在当30秒的时候,我通过循环访问每个clients的元素,发现是那个
Athread,然后断开连接,但是有时候常常出现错误。痛苦!!Delphi是不是不能做这样的实时通讯系统呢。
我采用的是windows的服务形式编写的程序。出现的错误不外乎两类
1.事件 ID ( 0 )的描述(在资源( MyServer.exe )中)无法找到。本地计算机可能没有必要的注册信息或消息 DLL 文件来从远端计算机显示消息。部分事件包含了下列信息: List index out of bounds (27).
2.事件 ID ( 0 )的描述(在资源( MyServer.exe )中)无法找到。本地计算机可能没有必要的注册信息或消息 DLL 文件来从远端计算机显示消息。部分事件包含了下列信息: Access violation at address 00403D71 in module 'BGServer.exe'. Read of address 01004338.
出第一个的时候还可以正常工作,第二个好像不行了像崩溃了似的。我的软件的要求是通过IdTcpServer作服务器端
在程序启动的时候有一个设备列表
当有设备连接服务器的时候通过查询列表
知道那个终端连接的
最后就是数据链路维护,当发现30秒连接的客户端没有数据强制断开连接
不知道那个高人有这样的构架,让小弟了解了解我的方式是仿照了delphi的例子作的
Clients:Tlist来维护连接
但就是这个clients出问题
在当30秒的时候,我通过循环访问每个clients的元素,发现是那个
Athread,然后断开连接,但是有时候常常出现错误。痛苦!!Delphi是不是不能做这样的实时通讯系统呢。
很可能出在:你删除了Clients中的节点后又访问了它(第一个错误)
或是你在List的Item里记录的线程已经结束,但你又访问了它(第二个错误)
http://community.csdn.net/Expert/topic/3197/3197739.xml?temp=.6519281
要是对上号,那咱再联系
indy是没有
不过Tlist有点不好控制
我曾经试图多次更改这个问题
用了很多方法,不过就是解决不了
如何控制Tlist的访问越界呢
我看到的Chat的例子,就是这样,而且也会出现
越界现象的to猛禽
我的list的item里面记录的线程已经结束时什么意思呢你在List的Item里记录的线程已经结束,但你又访问了它(第二个错误)楼上各位大虾帮忙给我指点一二,小弟将代码贴在下面了
type
TSimpleClient = class(TObject)
Thread: TIdPeerThread;
DNS:string;
port:longint;
name:string;
delete:boolean;
data:integer;
keep_s:integer;
newon:boolean;
FrameNumber:Smallint;
comstruct:Tcomstruct;
ms_buf:string;
Err:array[1..9] of byte;
end;procedure TServiceGprs.tcpserverConnect(AThread: TIdPeerThread);
var Client: TSimpleClient;
begin
{ try
check_DNS(athread);
except
;
end; }
Client := TSimpleClient.Create;
client.FrameNumber:=-1;
// client.Mslist.Create;
client.delete:=false;
{ Assign its default values }
{ Assign the thread to it for ease in finding }
client.DNS:=Athread.Connection.Socket.Binding.IP;
client.port:=Athread.Connection.Socket.Binding.Port; Client.Thread := AThread;
{ Assign it to the thread so we can identify it later }
AThread.Data := Client;
{ Add it to the clients list }
Clients.Add(Client);
client.newon:=true;
end;procedure TServiceGprs.tcpserverDisconnect(AThread: TIdPeerThread);
var
Client: TSimpleClient;
begin
//athread.Connection.Socket.Binding.PeerPort; //ip
{Retrieve Client Record from Data pointer }
Try
Client:=AThread.Data as Tsimpleclient;
client.delete:=true;
finally
begin
{$IFDEF Test_disconnect_process}
writelog('一个连接断开 client.name:"'+client.name+'"(如果为空为无连接)');
{$ENDIF}
AThread.Data := nil;
end;
end;
end;
procedure TServiceGprs.tcpserverExecute(AThread: TIdPeerThread);
var
msg:String;
Client: TSimpleClient;
len:Smallint;
ms_buf_len:word;
// i:integer;str:STRING;mytextfile:textfile;
begin
try
begin
Msg:= athread.Connection.CurrentReadBuffer;
Client := AThread.Data as TSimpleClient;
Client.ms_buf:=Client.ms_buf+msg;
ms_buf_len:=length(Client.ms_buf);
if ms_buf_len>=6 then
begin
len:=Ulenchk(ord(Client.ms_buf[len_exc]),ord(Client.ms_buf[len_exc+1]));
if (len>=0) and (len<=512) then
begin
if len<=ms_buf_len-con_len then
begin
recv_chk(copy(Client.ms_buf,1,len+con_len),client);
end;
if len=ms_buf_len-con_len then
begin
Client.ms_buf:='';
end;
if len<ms_buf_len-con_len then
Client.ms_buf:=copy(Client.ms_buf,len+con_len+1,ms_buf_len-len-con_len)
end
else
begin
Client.ms_buf:='';
end;
end;
end;
except
begin
{$IFDEF Test_receive}
writelog('Clients_ms_buf error'+client.name);
{$ENDIF}
end;
end;
// }
end;procedure TServiceGprs.client_keepTimer(Sender: TObject);
var count,index:integer;
Client: TSimpleClient;
list:Tlist;
begintry
list:=tcpserver.Threads.LockList;
count:=clients.Count;
if count<>0 then
begin
if list.count=0 then
begin
inc(CclearFlag);
if (CclearFlag>3) then
begin
clients.Clear;
CclearFlag:=0;
end;
end;
end;
finally
tcpserver.Threads.UnlockList;
end;for index:=count-1 downto 0 do
begin
try
Client := Clients.Items[index];
if not client.delete then
begin
if not Assigned(Client) then
begin
{$IFDEF Test_Client_keep}
writelog('(侦测到client=nil if not Assigned(Client) then) delete'+client.name);
{$ENDIF}
Clients.Delete(index);
end
else
begin
inc(client.keep_s);
if (client.keep_s>keep_counts) then
begin if not Client.Thread.Terminated then
begin
try
Begin
{$IFDEF Test_Client_keep}
writelog('(当连接'+inttostr(keep_counts)+'秒无信息服务器断连) Disconnect'+client.name);
{$ENDIF}
TIdPeerThread(Client.Thread).Connection.Disconnect;
End
except
begin
{$IFDEF Test_Client_keep}
writelog('(断开连接发生错误)DIS ERROR');
{$ENDIF}
end; end;
end;
{$IFDEF Test_Client_keep}
writelog('采集器名字'+client.name+'超时>30');
{$ENDIF}
// Clients.Delete(index);
client.delete:=true;
// FreeAndNil(client);
end;
end;
end
else
begin
Clients.Delete(index);
FreeAndNil(client);
end;
except
begin
clients.Delete(index);
{$IFDEF Test_Client_keep}
writelog('client_keepTimer处理过程发生错误Clients.items[index] error');
{$ENDIF}
end;
end;
end;
End;
两个问题可能都在client_keepTimer
一个问题出在Clients这个东东上
第二个可能发生在
TIdPeerThread(Client.Thread).Connection.Disconnect;
是不是Thread也就是Athread已经结束,我还要去通过上面的方式去强行断开
这样是不是就容易出现第二个错误呢。