다름이 아니라 동적으로 클라이언트를 생성했구요(스레드로)
그 스레드 갯수를 관리자가 동적으로 적용하게 되어있습니다. 그럼 서버쪽에서는 아이피를 몇십개 가지고 있더라도 이미 실행된 스레드의 증감에 따라 다시 돌고 다시 돌고 하겠죠...예를 들어 스레드는 10이고 아이피는 20개면 스레드가 10번 짝 돌면서 끝나면 나머지 10개의 아이피들이 빈 쓰레드를 사용해 커넥션을 맺는거죠..^^;
문제는 스레드가 Terminate 되지 않거나 ThreadList에서 Count가 감소하지 않는다는 얘긴데...여기 소스 전체 거덩요...제발 도와 주세요...
폼파일
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, scktcomp, ExtCtrls, ComCtrls;
type
TForm1 = class(TForm)
ClientSocket1: TClientSocket;
Button2: TButton;
Label1: TLabel;
Label2: TLabel;
Edit1: TEdit;
Edit2: TEdit;
procedure Button2Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
Trd_Cnt : Integer;
procedure SocketCreate(Cnt : Integer);
end;
var
Form1: TForm1;
implementation
uses unit2;
{$R *.DFM}
procedure TForm1.Button2Click(Sender: TObject);
var
localList : TList;
begin
ipAdd[0] := '192.168.0.65';
ipAdd[1] := '192.168.0.70';
ipAdd[2] := '192.168.0.72';
ipAdd[3] := '192.168.0.1';
ipAdd[4] := '192.168.0.71';
Cnt := 0; //<------------Ipaddress 갯수
//Recv_Cnt := 0;
MyList.Clear;
repeat
LocalList := MyList.LockList;
try
if LocalList.Count < 2 then //<---------------thread 갯수
begin
SocketCreate(Cnt);
Inc(Cnt);
end;
Application.ProcessMessages;
finally
MyList.UnlockList;
end;
until Cnt > 4;
with MyList.LockList do
try
while count > 0 do
Application.ProcessMessages;
finally
MyList.UnlockList;
end;
ShowMessage('Thread End');
end;
procedure TForm1.SocketCreate(Cnt : Integer);
begin
with ThSocket.Create(True)do
begin
FreeOnTerminate := True;
ipAddress := ipAdd[Cnt];
MyList.Add(@ipAddress);
Resume;
end;
//if Assigned(ThSocket) then
// ShowMessage('Alive')
//else ShowMessage('Die');
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
MyList := TThreadList.Create;
end;
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
MyList.Clear;
MyList.Destroy;
end;
end.
//스레드
unit Unit2;
interface
uses
Classes, scktcomp, Dialogs, Windows, sysutils, Forms, Messages;
type
pTTmpBase = ^TTmpBase;
TTmpBase = Record
Msg : DWORD;
end;
ThSocket = class(TThread)
private
{ Private declarations }
protected
procedure Execute; override;
procedure ConnectError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
procedure ReceiveMsg(Sender: TObject;
Socket: TCustomWinSocket);
procedure SendMsg(Sender: TObject;
Socket: TCustomWinSocket);
public
ipAddress : String;
end;
var
InCnt : Integer;
isEnd : Boolean;
Err : Integer;
OpenList ,
CloseList : TStringList;
MyList : TThreadList;
Cnt : Integer;
RecvBuffer ,
SendBuffer : array[0..4096] of Char;
ipAdd : array [0..8000] of String;
const
ALIVE = $FF000019;
ALIVE2 = $FF000020;
implementation
{ Important: Methods and properties of objects in VCL can only be used in a
method called using Synchronize, for example,
Synchronize(UpdateCaption);
and UpdateCaption could look like,
procedure ThSocket.UpdateCaption;
begin
Form1.Caption := 'Updated in a thread';
end; }
{ ThSocket }
procedure ThSocket.Execute;
var
ClientSocket : TClientSocket;
begin
isEnd := False;
ClientSocket := TClientSocket.Create(nil);
ClientSocket.Port := 7335;
ClientSocket.Address := ipAddress;
ClientSocket.OnError := ConnectError;
ClientSocket.OnRead := ReceiveMsg;
ClientSocket.OnConnect := SendMsg;
ClientSocket.Active := True;
repeat
Application.ProcessMessages;
until isEnd;
MyList.Remove(@ipAddress);
if Terminated then
Exit;
//Terminate;
end;
procedure ThSocket.ReceiveMsg(Sender: TObject;
Socket: TCustomWinSocket);
begin
Socket.ReceiveBuf(RecvBuffer, 4096);
if pTTmpBase(@RecvBuffer)^.Msg = ALIVE2 then
begin
Socket.Close;
isEnd := True;
end;
OpenList := TStringList.Create;
OpenList.Insert(0,IpAddress);
OpenList.Free;
end;
procedure ThSocket.ConnectError(Sender: TObject;
Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
var ErrorCode: Integer);
begin
showmessage(IpAddress + ' ErrorCode=' + IntToStr(ErrorCode));
CloseList := TStringList.Create;
CloseList.Insert(0, IpAddress);
CloseList.Free;
ErrorCode := 0;
isEnd := True;
end;
procedure ThSocket.SendMsg(Sender: TObject;
Socket: TCustomWinSocket);
begin
FillChar(SendBuffer, 4096, #0);
pTTmpBase(@SendBuffer)^.Msg := ALIVE;
Socket.SendBuf(SendBuffer, SizeOf(DWORD));
end;
end.