Q&A

  • 진짜좀 도와 주세용 흑....미치기 일보직전...쩝.
다름이 아니라 동적으로 클라이언트를 생성했구요(스레드로)

그 스레드 갯수를 관리자가 동적으로 적용하게 되어있습니다. 그럼 서버쪽에서는 아이피를 몇십개 가지고 있더라도 이미 실행된 스레드의 증감에 따라 다시 돌고 다시 돌고 하겠죠...예를 들어 스레드는 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.

0  COMMENTS