####### 지금부터 소스 입니다. ######################
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