Delphi 6 indy连接悬挂

Delphi 6 indy连接悬挂,delphi,sockets,indy,Delphi,Sockets,Indy,我有个小问题。在我建立了服务器和客户端之间的连接之后。我会先关闭客户端,然后关闭服务器,但服务器挂起并向我发送“程序已崩溃”消息。我认为我遇到的问题是服务器无法识别客户端已断开连接,并且仍然认为客户端处于活动状态。以下是源代码: 客户: unit client; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ScktComp, Win

我有个小问题。在我建立了服务器和客户端之间的连接之后。我会先关闭客户端,然后关闭服务器,但服务器挂起并向我发送“程序已崩溃”消息。我认为我遇到的问题是服务器无法识别客户端已断开连接,并且仍然认为客户端处于活动状态。以下是源代码:

客户:

unit client;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, Winsock, IdBaseComponent, IdComponent,
  IdTCPConnection, IdTCPClient;

type
  TForm1 = class(TForm)
    IdTCPClient1: TIdTCPClient;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

function GetIpFromDns(HostName: string): string;
type
  tAddr = array[0..100] of PInAddr;
  pAddr = ^tAddr;
var
  I: Integer;
  WSA: TWSAData;
  PHE: PHostEnt;
  P: pAddr;
begin
  Result := HostName;
  WSAStartUp($101, WSA);
  try
    PHE := GetHostByName(pChar(HostName));
    if (PHE <> nil) then
    begin
  P := pAddr(PHE^.h_addr_list);
  I := 0;
  while (P^[i] <> nil) do
  begin
  Result := (inet_nToa(P^[i]^));
  Inc(I);
  end;
    end;
  except
  end;
  WSACleanUp;
end;





procedure TForm1.FormCreate(Sender: TObject);
begin
IdTCPClient1.Host := GetIpFromDns('example.no-ip.org');
IdTCPClient1.Port := 9000;
IdTCPClient1.Connect;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if IdTCPclient1.Connected = True then
IdTCPClient1.Disconnect
else
end;

end.
看起来我并没有为indy设置监听端口,但我在object inspector页面中设置了。出于某种原因,如果我将IdTCPServer.DefaultPort和Active放在表单create中,它会抛出更多错误

我还尝试了IdTCPClient1.DisconnectSocket,但也没有成功


我是否需要在服务器端创建一些东西来定期检查连接?如果是这样,最好的方法是什么?

在服务器线程的上下文中调用方法IdTCPServer1Connect。使用synchronize在主VCL线程中执行它。它是否与本地主机而不是GetIpFromDns('example.no ip.org')一起工作?为了进一步澄清mjn的评论,
ShowMessage
是VCL代码而不是线程安全的。您不需要
GetIpFromDns()
。将
Host
设置为
example.no ip.org
并让
Connect()
为您解决此问题。您应该手动解析的唯一原因是主机名有多个IP,在这种情况下,您应该循环连接到每个IP的每个IP,直到成功。但是,如果您只关心连接到一个IP,那么让Indy为您完成这项工作。此外,
TIdTCPServer
需要分配
OneExecute
事件处理程序,否则
Active
属性设置程序将在运行时激活服务器时引发异常。
unit server;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ScktComp, IdBaseComponent, IdComponent, IdTCPServer;

type
  TForm1 = class(TForm)
    IdTCPServer1: TIdTCPServer;
    procedure IdTCPServer1Connect(AThread: TIdPeerThread);
    procedure IdTCPServer1Disconnect(AThread: TIdPeerThread);



  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
begin
showmessage('client connected');
end;

procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);
begin
showmessage('client disconnected');
end;



end.