2012-11-13 2 views
1

소켓에서 데이터를 읽는 Delphi 2009 응용 프로그램을 작성해야합니다. 이렇게하려면 TIdTCPServer.OnExecute 이벤트에 대한 이벤트 처리기를 작성해야합니다.콘솔 응용 프로그램에서 TIdTCPServer.OnExecute

GUI 응용 프로그램에서이 기능을 구현하는 예제가 많이 발견되었지만 콘솔 응용 프로그램 (창 없음)에서 수행해야합니다.

받은 모든 메시지를 디버그 출력에 출력하는 이벤트 처리기 (TCPServer에 첨부)를 추가하려면 아래 코드를 어떻게 수정해야합니까?

unit ReceivingThreadUnit; 

interface 

uses 
    Classes, 
    IdTCPServer, 
    IdSocketHandle, 

    SysUtils, 
    Windows; 

type 
    ReceivingThread = class(TThread) 
    private 
     TCPServer: TIdTCPServer; 
    public 
     procedure Run(); 

    end; 

implementation 

procedure ReceivingThread.Run(); 
var 
    Bindings: TIdSocketHandles; 
begin 
    TCPServer := TIdTCPServer.Create(nil); 

    //setup and start TCPServer 
    Bindings := TIdSocketHandles.Create(TCPServer); 
    try 
    with Bindings.Add do 
    begin 
     IP := '127.0.0.1'; 
     Port := 9998; 
    end; 
    try 
     TCPServer.Bindings:=Bindings; 
     // Here I want to attach TCPServer to an OnExecute event handler 
     TCPServer.Active:=True; 
    except on E:Exception do 
     OutputDebugString(PChar(E.ToString)); 
    end; 
    finally 
    Bindings.Free; 
    TCPServer.Free; 
    end; 
    TCPServer.Active := true; 
end; 

end. 

답변

1

클래스에 이벤트 처리기를 추가해야합니다. 그리고 그것을 연결 :

TCPServer.OnExecute := Self.ExecuteHandler; 
4

다윗이 말했다 (하지만 완전히 쇼를하지 않았다), 당신은 당신의 스레드 클래스의 메서드를 선언 한 후 OnExecute 이벤트에 할당해야합니다.

참고로 TIdSocketHandles 컬렉션을 수동으로 만들어서는 안됩니다. 대신 TIdTCPServer.Bindings 컬렉션의 Add()으로 전화하십시오.

이을 시도해보십시오 말했다와

unit ReceivingThreadUnit; 

interface 

uses 
    Classes, 
    IdTCPServer, 
    IdSocketHandle, 
    IdContext, 

    SysUtils, 
    Windows; 

type 
    ReceivingThread = class(TThread) 
    private 
    TCPServer: TIdTCPServer; 
    procedure ExecuteHandler(AContext: TIdContext); 
    public 
    procedure Run; 
    end; 

implementation 

procedure ReceivingThread.ExecuteHandler(AContext: TIdContext); 
begin 
    //... 
end; 

procedure ReceivingThread.Run; 
begin 
    //setup and start TCPServer 
    TCPServer := TIdTCPServer.Create(nil); 
    try 
    with TCPServer.Bindings.Add do 
    begin 
     IP := '127.0.0.1'; 
     Port := 9998; 
    end; 
    TCPServer.OnExecute := ExecuteHandler; 
    try 
     TCPServer.Active := True; 
    except 
     on E: Exception do 
     OutputDebugString(PChar(E.ToString)); 
    end; 
    while not Terminated do 
     Sleep(1000); 
    TCPServer.Active := False; 
    finally 
    TCPServer.Free; 
    end; 
end; 

end. 

, 당신의 receiveing ​​스레드가 꽤 중복 TIdTCPServer 이미 멀티 스레드이기 때문에, 당신은 다른 방법 단지 모두 스레드 클래스를 제거 할 수 있도록 :

program MyApp; 

{$APPTYPE CONSOLE} 

{$R *.res} 

uses 
    Classes, 
    IdTCPServer, 
    IdSocketHandle, 
    IdContext, 

    SysUtils, 
    Windows; 

type 
    TCPServerEvents = class 
    public 
    class procedure ExecuteHandler(AContext: TIdContext); 
    end; 

class procedure TCPServerEvents.ExecuteHandler(AContext: TIdContext); 
begin 
    //... 
end; 

var 
    TCPServer: TIdTCPServer; 
begin 
    //setup and start TCPServer 
    TCPServer := TIdTCPServer.Create(nil); 
    try 
    with TCPServer.Bindings.Add do 
    begin 
     IP := '127.0.0.1'; 
     Port := 9998; 
    end; 

    TCPServer.OnExecute := TCPServerEvents.ExecuteHandler; 

    try 
     TCPServer.Active := True; 
    except 
     on E: Exception do 
     OutputDebugString(PChar(E.ToString)); 
    end; 

    while (not stop condition) do 
     Sleep(1000); 

    TCPServer.Active := False; 
    finally 
    TCPServer.Free; 
    end; 
end. 
+0

을 좋은. 조금 더러운 물체로 당신의 트릭을 찾았습니다. 하지만 왜 객체를 인스턴스화하고 싶지 않은지 이해합니다. 좋은 변형은 클래스 메서드를 사용하는 것입니다. 물론 클래스를 선언해야하지만, 보일 플레이트의 주요 비트 인 인스턴스를 인스턴스화 할 필요는 없습니다. –

+0

감사합니다. 나는 그것을 사용하기 위해 나의 대답을 업데이트했다. –

관련 문제