====关于Indy和Dll的问题??=====

lz_0618 2004-06-23 01:40:01
想把包含TIdTCPServer控件的Form放到DLL中,却发现有很多问题!
当在调用的程序中显示该Form时,和正常的程序中是一样的,但在不显示Form时,问题来了,1) 当客户端断开时不触发OnDisconnect 2) 启动Server也会出现问题,当所有代码写在Form中的一个成员函数中时,服务起来了,但调用该DLL的Form的刷新出问题了,但把同样的代码拷贝到DLL的函数中却没有问题!

真是一头雾水!!

但用TServerSocket时OnDisconnect却没有问题!!!

谁做过,能给一些建议吗??
...全文
171 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
lz_0618 2004-06-28
  • 打赏
  • 举报
回复
有问题吗?
lz_0618 2004-06-26
  • 打赏
  • 举报
回复
unit Unit1;
interface

uses
Windows, Messages, SysUtils, Classes,
Dialogs, IdBaseComponent, IdComponent, IdTCPServer;
type
TSimpleClient = class(TObject)
DNS,
IP,
Name : String;
ListLink : Integer;
Thread : Pointer;
end;
type
TIndyServer = class(TObject)
private
IdTCPServer: TIdTCPServer;
FClients:TList;
procedure IdTCPServerConnect(AThread: TIdPeerThread);
procedure IdTCPServerDisconnect(AThread: TIdPeerThread);
procedure IdTCPServerExecute(AThread: TIdPeerThread);
procedure IdTCPServerException(AThread: TIdPeerThread;
AException: Exception);
Procedure DisconnectAllClient();
public
constructor Create;
Destructor Destroy();override;

procedure StartServer();
procedure StopServer();
procedure SendMsgToAllClients();
end;

implementation

uses StrUtils,UCmdSendPub;

//======================================================
constructor TIndyServer.Create();
begin
inherited Create;
IdTCPServer := TIdTCPServer.Create(nil);
FClients := TList.Create();
IdTCPServer.DefaultPort := 6060;
IdTCPServer.OnConnect := IdTCPServerConnect;
IdTCPServer.OnDisconnect := IdTCPServerDisconnect;
IdTCPServer.OnExecute := IdTCPServerExecute;
IdTCPServer.OnException := IdTCPServerException;
StartServer();
end;

destructor TIndyServer.Destroy();
var
i:Integer;
Client:TSimpleClient;
begin
StopServer();

for i := 0 to FClients.Count -1 do
begin
Client := TSimpleClient(FClients.Items[i]);
TIdPeerThread(Client.Thread).Connection.DisconnectSocket;
Client.Free();
end;
FClients.Free();
IdTCPServer.Free;

inherited Destroy;
end;

procedure TIndyServer.StartServer();
begin
IdTCPServer.Active := True;
end;

procedure TIndyServer.StopServer();
begin
//DisconnectAllClient();
IdTCPServer.Active := False;
IdTCPServer.Bindings.Clear;

end;

procedure TIndyServer.IdTCPServerConnect(AThread: TIdPeerThread);
var
Client:TSimpleClient;
begin
AThread.Connection.WriteLn('100: 欢迎连接到简单TCP服务器!');

Client := TSimpleClient.Create();
Client.IP := AThread.Connection.Socket.Binding.PeerIP;
Client.Name := inttostr(FClients.Count)+':'+ AThread.Connection.Socket.Binding.PeerIP;
Client.ListLink := FClients.Count;
Client.Thread := AThread;

FClients.Add(Client);

AThread.Data := Client;
end;

procedure TIndyServer.IdTCPServerExecute(AThread: TIdPeerThread);
var
sCommand: string;
begin
with AThread.Connection do
begin
try
sCommand := ReadLn();

if sCommand <> 'QUIT' Then
WriteLn('200: 数据接收成功!')
else
AThread.Connection.DisconnectSocket;
finally

end;

end;
end;

procedure TIndyServer.IdTCPServerDisconnect(AThread: TIdPeerThread);
var
i:integer;
Client:TSimpleClient;
begin
if not Assigned(AThread.Data) then
exit;
for i := 0 to FClients.Count -1 do
begin
if AThread.Data = FClients.Items[i] then
begin
Client := (FClients.Items[i]);
Client.Free();
FClients.Delete(i);
AThread.Data := nil;
end;
end;

end;

procedure TIndyServer.SendMsgToAllClients();
Var
i:Integer;
Msg:String;
APeer:TIdPeerThread;
AList:TList;
begin
AList := IdTCPServer.Threads.LockList;
try
if AList.Count>0 then
begin
Msg := InputBox('发送消息','请输入','');
//给所有客户发消息
for i := 0 to AList.Count -1 do
begin
APeer := TIdPeerThread(AList.Items[i]);
APeer.Connection.WriteLn(Msg);
end;
//TIdPeerThread(IdTCPServer.Threads.LockList.Items[0]).Connection.WriteLn(Msg);
end;
finally
IdTCPServer.Threads.UnlockList();
end;
end;

Procedure TIndyServer.DisconnectAllClient();
Var
i:Integer;
APeer:TIdPeerThread;
AList:TList;
begin

AList := IdTCPServer.Threads.LockList;
try
if AList.Count>0 then
begin
for i := 0 to AList.Count -1 do
begin
APeer := TIdPeerThread(AList.Items[i]);
APeer.Connection.DisconnectSocket;
APeer.Data := nil;
end;
end;

for i := 0 to FClients.Count-1 do
begin
TSimpleClient(FClients.Items[0]).Free();
FClients.Delete(0);
end;

finally
IdTCPServer.Threads.UnlockList();
end;
end;

procedure TIndyServer.IdTCPServerException(AThread: TIdPeerThread;
AException: Exception);
begin
AThread.Connection.DisconnectSocket();
ShowMessage(AException.Message);
end;

end.
tonylk 2004-06-25
  • 打赏
  • 举报
回复
你的TObject继承下来的这个类,在访问Form的时候是怎么做的?估计这里写得不对。。你先把Form访问的代码评比掉看看对不对。
一般这种情况下:在你自己的类中做一个事件属性,在信息到达时,调用该事件。
Form在Create时,将该类的事件属性设置为自身的某个方法,在Destroy时,再将它设回nil。。这样一般不会有地址访问错误的。

关于调试,可以试着设置一下工程的DebugSourcePath属性。。
tonylk 2004-06-25
  • 打赏
  • 举报
回复
晕。。。
lz_0618 2004-06-25
  • 打赏
  • 举报
回复
正是不知道应该帖哪些,所以没有办法贴出来啊!!!
tonylk 2004-06-25
  • 打赏
  • 举报
回复
代码你还是在这里贴吧,贴些你觉得相关的。。
lz_0618 2004-06-25
  • 打赏
  • 举报
回复
TO tonylk(=www.tonixsoft.com=):
Form已经全部去掉!

DebugSourcePath属性设置也没有用!!!

你要是有时间,留下你的Email我把代码发给你,你帮我看看!!

lz_0618 2004-06-24
  • 打赏
  • 举报
回复
专门从TObject继承了一个类,这下OnDisconnect是调用了,但在有客户端连接的情况下,断开服务器端,出现EIdTerminateThreadTimeout错误,不在动态连接库时出现该错误,是因为在OnDisconnect中有对界面操作的语句,但在我的DLL中,根本没有此类语句啊????!!!!!

另外,我的这个工程组还有个怪毛病,当关闭该组,再打开,设置的断点就不起作用了(调试时停不下来),只有在删除DOF文件,再打开,重新编译才可以调试,真是怪了,也不知是否和程序中有条件编译的语句有没有关系!!!!!!!!?????????????

谁能帮我看一下源代码???
tonylk 2004-06-24
  • 打赏
  • 举报
回复
既然你在不显示Dll中的这个Form的时候也需要网络功能,那何必把IdServer放在Form中呢,
另外做一个类,专门负责网络连接,在家在Dll后立即启动这个类,在结束Dll时在Free它。
brallow 2004-06-24
  • 打赏
  • 举报
回复
我是没有用过,对不起了..
feitian2004 2004-06-24
  • 打赏
  • 举报
回复
我感觉应该是可以的
lz_0618 2004-06-24
  • 打赏
  • 举报
回复

看来需要试验了,不知放在非Form的类中是否会有问题?!
lz_0618 2004-06-24
  • 打赏
  • 举报
回复
看来没有人这么用过!!!
lzy6204 2004-06-23
  • 打赏
  • 举报
回复
没做过!

5,392

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧