Q&A

  • 멀티스레드이용시 실행중인 스레드체크 및 강제종료 방법....

TServerClientThread 를 이용해서 소켓프로그램을 작성중입니다.


통신은 잘되고 있고 다중스레드 처리까지 되었습니다.

근데 문제가 있습니다.

프로그램 종료시에 현재 데이터를 읽고있거나  쓰고 있을때 처리를 어떻게 해야 할지 모르겠습니다.

 

========= 소스부분=========================
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  ServerSocket1.Close;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
  ServerSocket1.Port := 10109;
  ServerSocket1.ServerType := stThreadBlocking;
  ServerSocket1.ThreadCacheSize := 10;
  ServerSocket1.Active := true;
end;

procedure TForm1.ServerSocket1GetThread(Sender: TObject;
  ClientSocket: TServerClientWinSocket;
  var SocketThread: TServerClientThread);
begin
  Caption := IntToStr(ServerSocket1.Socket.ActiveConnections);
  if ServerSocket1.Socket.ActiveConnections > 100 then begin
    // 접속 수 제한
    ClientSocket.Close;
  end
  else begin
    // 클라이언트 스레드 생성
    SocketThread := TMyServerClient.Create(False, ClientSocket);
  end;
end;

procedure TForm1.ServerSocket1ThreadEnd(Sender: TObject;
  Thread: TServerClientThread);
begin
  Caption := IntToStr(ServerSocket1.Socket.ActiveConnections);
end;

procedure TForm1.ServerSocket1ClientError(Sender: TObject;
  Socket: TCustomWinSocket; ErrorEvent: TErrorEvent;
  var ErrorCode: Integer);
begin
  ErrorCode := 0;
end;

// 클라이언트 스레드 시작
procedure TMyServerClient.ClientExecute;
var Stream : TWinSocketStream;
  inBuf , OutBuf : array[0..1023] of AnsiChar;
  Buffer , strCmd , strRet : String;
  iTimeOut, i: Integer;
begin
  iTimeOut := 60000;

  try
    Stream := TWinSocketStream.Create( ClientSocket, iTimeOut );
    if ClientSocket.Connected then begin
      FillChar(OutBuf, 1024, 0);
      StrPCopy(OutBuf, 'WellCome!');
      Stream.Write(OutBuf, StrLen(OutBuf));
    end;

    Buffer := '';
    while (not Terminated) and ClientSocket.Connected do begin
      if Not Stream.WaitForData(iTimeOut) then begin
        ClientSocket.Close;
        Break;
      end;
      try
        i := Stream.Read(inBuf, 1024);
      except
        ClientSocket.Close;
        Break;
      end;

      if i = 0 then begin
        ClientSocket.Close;
        Break;
      end;

      inBuf[i] := #0;
      Buffer := Buffer + StrPas(inBuf);

      Form1.Memo1.Lines.Add(Buffer);

      Stream.Write(inBuf, StrLen(inBuf));

      i := Pos(#13#10,Buffer);
      if i > 0 then begin
        strCmd := LowerCase(Copy(Buffer, 1, i -1));
        Buffer := '';

        StrPCopy(OutBuf,'Good Bye~!'+#13#10#0);
        Stream.Write(OutBuf, StrLen(OutBuf));

      end;
    end;
  except
    HandleException;
  end;
  Stream.Free;
end;

=================================================
위와같이 코딩을 했고 ClientExecute 에 비지니스 로직을 넣었습니다.
문제는 접속하고 통신하고는 아무런 문제가 없는데, 10초마다 통신이 이루어지고 있는데, 중간에 프로그램을 종료하게되면, 소켓 read, wirte 에러가 납니다.
스레드에서 읽고 있거나, 쓰고 있기때문에 에러가 나는것 같은데, 어떻게 해야 될지 감이 안잡히네요.
실행중인 스레드가 몇개인지 체크해서, 스레드를 강제종료 해주면 될것 같기는 한데...


간단한 예제같은게 있거나 참조할게 있다면 알려주시면 감사하겠습니다.

고수님들의 도움이 절실히 필요합니다.

 

미리 감사인사드립니다.. 꾸벅~


즐거운 주말되세요.

2  COMMENTS
  • Profile
    이정욱 2014.03.02 05:48

    Terminate를 하시고 WaitFor로 대기 하시면 됩니다.

    그리고 쓰레드안의 루프 안에서 종료 변수하나를 두시고 체크 하시면서 돌면 됩니다.


  • Profile
    마당쇠 2014.03.03 00:35

    감사합니다.

    어찌해야 할지 감도 몾잡고있었는데 덕분에 해결했습니다.


    한번더 감사드립니다. 꾸벅~~~~