단순한 채팅프로그램인데요.
한 프로그램상에 서버와 클라이언트가 모두 구현되어 있습니다.
프로그램을 실행시켜서 서버 모드로 실행하게 하고
프로그램을 하나 더 띄워서 클라이언트 모드로 실행하게 합니다.
그후에 클라이언트에서 서버로 접속후
클라이언트에서 글을쓰면 정상적으로 서버로 전송이 되는데
문제는...
서버에서 글을 쓰면
서버가 다운이 되버리네요.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, IdBaseComponent, IdComponent, IdTCPConnection, IdTCPClient, ExtCtrls,
StdCtrls, IdTCPServer, IdContext;
type
TForm1 = class(TForm)
Edit1: TEdit;
Button1: TButton;
Memo1: TMemo;
Edit2: TEdit;
Edit3: TEdit;
Timer1: TTimer;
IdTCPClient1: TIdTCPClient;
IdTCPServer1: TIdTCPServer;
Button2: TButton;
procedure Button2Click(Sender: TObject);
procedure IdTCPServer1Execute(AContext: TIdContext);
procedure Timer1Timer(Sender: TObject);
procedure Edit3KeyPress(Sender: TObject; var Key: Char);
procedure IdTCPClient1Disconnected(Sender: TObject);
procedure IdTCPClient1Connected(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
if IdTCPClient1.Connected then
begin
IdTCPClient1.Disconnect;
Button1.Caption:='Connect';
end
else
begin
IdTCPClient1.Host:=Edit1.Text;
IdTCPClient1.Port:=2010;
IdTCPClient1.Connect;
Button1.Caption:='Disconnect';
end;
end;
procedure TForm1.IdTCPClient1Connected(Sender: TObject);
begin
Memo1.Lines.Add('Connection to '+Edit1.Text+' is complete');
end;
procedure TForm1.IdTCPClient1Disconnected(Sender: TObject);
begin
Memo1.Lines.Add('Disconnection to '+Edit1.Text+' is complete');
end;
procedure TForm1.Edit3KeyPress(Sender: TObject; var Key: Char);
var
i:integer;
begin
if Key = #13 then // 엔터키가 눌러졌을 경우
begin
if IdTCPClient1.Connected then // 클라이언트 일경우
begin
// 소켓에 ID와 글의 내용을 한 문자열로 만든후 쓴다.
IdTCPClient1.Socket.WriteLn(Edit2.Text+' : '+Edit3.Text);
end
else // 서버 일경우
begin
// 자신의 메모창에 쓴 글의 내용을 ID와 함께 출력한다.
Memo1.Lines.Add(Edit2.Text+' : '+Edit3.Text);
try
// 루프를 돌면서 서버에 접속되어있는 모든 클라이언트들에게 메세지를 전송한다.
for i:=0 to IdTCPServer1.Contexts.LockList.Count-1 do <== 이 부분에서 멈추더군요
// 서버에 접속되어 있는 i번째 쓰레드의 소켓에 글의 내용과 ID를 한 문자열로 해서 쓴다.
TIdContext(IdTCPServer1.Contexts.LockList.Items[i]).Connection.Socket.WriteLn(Edit2.Text + ' : ' + Edit3.Text);
finally
IdTCPServer1.Contexts.UnlockList; // threads list 자원을 해제해준다.
end;
end;
Edit3.Clear; // 다음 내용을 입력받기 위해서 Edit3 창을 클리어 시켜준다.
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
var
rcv:string;
begin
if IdTCPClient1.Connected then // 클라이언트 모드일경우
begin
rcv:=IdTCPClient1.Socket.ReadLn('',10); // 소켓에서 받은 내용을 읽어와 rcv에 담는다.
if rcv <> '' then // 빈 문자열이 아닐경우에만
Memo1.Lines.Add(rcv); // rcv 내용을 Memo1에 출력한다.
end
end;
procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);
var
rcv:string;
i:integer;
begin
try
rcv:= AContext.Connection.Socket.Readln('',10);
if rcv<>'' then
Memo1.Lines.Add(rcv);
try
for i:=0 to IdTCPServer1.Contexts.LockList.Count-1 do
TIdContext(IdTCPServer1.Contexts.LockList.Items[i]).Connection.Socket.WriteLn(rcv);
finally
IdTCPServer1.Contexts.UnlockList;
end;
except
AContext.connection.disconnect;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
Button1.Enabled:=false;
Button2.Enabled:=false;
IdTCPServer1.Active:=true;
end;
end.
흑 어렵네요 ㅡㅡ;;;