Q&A

  • 종료된 clinet 의 IP 를 받아 오려면
#######    지금부터 소스 입니다. ######################
var
  Form1: TForm1;
  connList : TStringList;
implementation

{$R *.dfm}

// 클라이언트 가 접속 시
procedure TForm1.IdTCPServer1Connect(AThread: TIdPeerThread);
var
    connClientIP : string;
begin
    // 접속된 ip 를 가져온다.
    connClientIP := Athread.Connection.Binding.PeerIP;

    connList.Add(connClientIP);
    logWrite('Connect',Athread.Connection.Binding.PeerIP);
    updateClientList();
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
    // StringList 생성
    connList := TStringList.Create();
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
    // StringList 해제
    connList.Free();
end;

// 클라이언트가 종료 시
procedure TForm1.IdTCPServer1Disconnect(AThread: TIdPeerThread);
var
    index : integer;
    disconnClientIP : string;
begin
    // 종료된 ip 를 가져온다.
    disconnClientIP := AThread.Connection.Binding.PeerIP;
    for index:=0  to  connList.count -1 do
    begin
        if connList.Find(disconnClientIP,index) then
        begin
            connList.Delete(index);
            break;
        end;
    end;
    logWrite('Disconnect',disconnClientIP);
    updateClientList();
end;

// 클라이언트가 보낸 데이타를 읽는다.
procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var
    str : string;
begin
    logWrite('Execute Begin',Athread.Connection.Binding.PeerIP);
    with Athread.Connection do
    begin
        try
            logWrite('read before',Athread.Connection.Binding.PeerIP);
            str := ReadLn();
            logWrite('read string' + str,Athread.Connection.Binding.PeerIP);
            logWrite('read after',Athread.Connection.Binding.PeerIP);
        except
            logWrite('except enter',Athread.Connection.Binding.PeerIP);
        end;
    end;
    logWrite('Execute End',Athread.Connection.Binding.PeerIP);
end;

// 클라이언트 리스트를 업데이트 해준다.
procedure TForm1.updateClientList();
var
    index : integer;
    str : String;
const
    EOL : string = #13#10;
begin
    edtConnList.Text := '';
    for index:=0  to connList.Count-1 do
    begin
        str := connList[index];
        edtConnList.Text := edtConnList.Text + str;
    end;
end;

// 로그를 찍어준다.
procedure Tform1.logWrite(strMsg : string; strIP : string);
var
  RecFH     : TextFile;
  LogFile   : string;
  strTemp   : string;
  strHeader : string;   // 날짜 VAN 사 이름
  strTime   : string;   // 로그에 적는 시간
begin
    LogFile := ExtractFilePath(ParamStr(0))+ 'trace.log';

    SysUtils.ShortDateFormat := 'hhmmss';
    strTime := DateToStr(Now);

    strHeader := '[' +  copy(strTime,1,2) + ':'
               +        copy(strTime,3,2) + ':'
               +        copy(strTime,5,2) + ']';

    try
        AssignFile(RecFH, LogFile); //파일 만들기
        if FileExists(LogFile) then
            Append(RecFH)
        else
            Rewrite(RecFH);

        strTemp :=  strHeader + '[' + strIP + '] ' + strMsg;

        Writeln(RecFH,strTemp);

        CloseFile(RecFH);
    except
    end;
end;

##############          소스 종료    ##########################
클라이언트가 Connection List 관리 및 다른 작업과 연결하기 위해 간단히 테스트로 만든겁니다.
이 코드에서 문제점이 클라이언트가 종료 요청 시 OnExecute 이벤트에서 ReadLn 을 읽지 못해
바로 except 로 빠지고, OnDisConnect 이벤트로 넘어가는데, 문제는 클라이언트의 IP 를 알아오지
못합니다. 클라이언트가 종료 요청 시, 종료 요청한 IP 를 어떻게 받아와야 되는지 알고 싶습니다.

[ 결과 화면입니다.]
* 표하고 언급한 것은 코드 분석을 용이하게 하기 위해서 제가 쓴 겁니다.
*********     클라이언트가 서버에 접속 시도     *****************
[18:31:51][192.168.0.11] Connect
[18:31:51][192.168.0.11] Execute Begin
[18:31:51][192.168.0.11] read before            
*********     클라이언트가 서버에 데이터를 보냄 ***************
[18:32:03][192.168.0.11] read stringD136900001120040223183203K5404866657062001=0802                  0000001010700084                                                                                                  
[18:32:03][192.168.0.11] read after
[18:32:03][192.168.0.11] Execute End
[18:32:03][192.168.0.11] Execute Begin
[18:32:03][192.168.0.11] read before
*********     클라이언트가 서버에 DisConnect 요청 *************
[18:34:29][] except enter
[18:34:29][] Execute End
[18:34:29][] Disconnect
0  COMMENTS