Q&A

  • Indy를 이용한 Client 통신 프로그램 실행중 프로그램이 갑자기 종료되는 현상
Indy 컴포넌트를 이용해서 덱스트 데이타를 송/수신 하는 클라이언트 프로그램을 하고 있습니다.
오라클 디비에서 데이타를 읽어서 일정한 포맷의 텍스트 데이타를 만들고 서버에 송신(Send_Message 함수 호출) 하고 수신된 텍스트 데이타를 받는 프로그램 입니다.

궁금한 사항은,,,

(하나)
프로그램이 실행 되다가 그냥 종료되어 버립니다.
디버깅을 해보았지만 종료되는 위치가 일정치 아니하여 원인을 찾기가 힘이 듭니다.

(둘)
"전송버튼"으로 메시지를 송수신 하고 있는데, 정상적인 경우라면 "송신 -> 수신" 이 번갈아가며 진행 되어야지만 버튼틀릭을 빨리하여 실행을 하게되면 "송신 -> 송신 -> 수신" 등과 같이 수신 혹은 송신이 두차례 연달아 진행됩니다.(로그화일 기록에 의하면)
실제 프로그램 운영때에는는 디비를 읽어서 EOF 까지 루프를 돌게되는데, 이경우 더 심각한 상황이 나타날 수 있습니다.

(진짜 중요한 질문 셋)
긴 문장이지만 귀하신 답변 기다리겠습니다.
(아울러 프로그램 안전상 개선할 부분이 있으면 조언 바랍니다)

감사합니다.

우선 클라이언트와 서버간의 데이타 송수신에 사용 될 변수 선언 입니다.

### Global_Unit 이라는 외부 Unit에서 선언한 변수
type
  TCommBlock = record
                 Comm_Message : array[0..299] of char;
               end;
              

###  본문 프로그램에서 선언한 변수
  TClientHandleThread = class(TThread)
    private
      CB: TCommBlock;

  통신을 위한 아래의 프로시져 가 있습니다.


다음은 데이타 송수신 프로그램 본문 소스 입니다
//=========================================================================            
//텍스트 데이타를 서버로 전송함
//파라메터 "S : String" 은 송신할 텍스트 고정길이 300 바이트 데이타 입니다.
//=========================================================================
procedure TClientFrmMain.Send_Message(S : String);
var
  CommBlock : TCommBlock;
begin
  if Client.Connected = False then
     ClientConnect;

  CommBlock.Comm_Message := '';
  StrPcopy(CommBlock.Comm_Message, S);
  Client.WriteBuffer(CommBlock, 300, TRUE);
end;

//=========================================================================
//서버측으로부터 메시지 수신
//=========================================================================
procedure TClientHandleThread.Execute;
begin
  while not Terminated do
  begin
    if not ClientFrmMain.Client.Connected then
    begin
      Terminate;
      ClientFrmMain.Client.Disconnect;
    end
    else
    try
      ClientFrmMain.Client.ReadBuffer(CB, 300);
      Synchronize(HandleInput);
    except
    end;
  end;
end;

//=========================================================================
// 서버측으로 부터 들어오는 텍스트 데이타를 CB에 대입하고 로그화일에
// 텍스트 송신, 수신 내용을 기록함
//=========================================================================
procedure TClientHandleThread.HandleInput;
begin
  //  텍스트 데이타  수신 (업무 A 에 해당하는)
  if ((Copy(CB.Comm_Message, 20, 4) = '0810') and (Copy(CB.Comm_Message, 24, 3) = '100')) then
  begin
     JOB_START_MESSAGE_RECEIVE     := CB.Comm_Message;
     ClientFrmMain.Write_Log('업무 A 텍스트 송신' + '['+DateTimeToStr(Now) + ']' + JOB_START_MESSAGE_SEND);
     ClientFrmMain.Write_Log('업무 A 텍스트 수신' + '['+DateTimeToStr(Now) + ']' + JOB_START_MESSAGE_RECEIVE);
  end;

  // 텍스트 데이타  수신 (업무 B 에 해당하는)
  if ((Copy(CB.Comm_Message, 20, 4) = '0100') and (Copy(CB.Comm_Message, 24, 3) = '100')) then
  begin
    JOB_DOING_MESSAGE_RECEIVE := CB.Comm_Message;
    ClientFrmMain.Write_Log('업무 B 텍스트' + '['+DateTimeToStr(Now) + ']' + JOB_DOING_MESSAGE_SEND);
    ClientFrmMain.Write_Log('업무 B 텍스트' + '['+DateTimeToStr(Now) + ']' + JOB_DOING_MESSAGE_RECEIVE);
  end;
end;

//=========================================================================
//서버와 Connect 함.
//=========================================================================
Procedure TClientFrmMain.ClientConnect;
begin
  try
    Client.Connect(600000);
    Client.ReadTimeout := 600000; // 수신시 60초 동안 응답이 없으면 소켓접속 해제를 위한 시간 설정.
    ClientHandleThread := TClientHandleThread.Create(True);
    ClientHandleThread.FreeOnTerminate:=True;
    ClientHandleThread.Resume;
  except
    on E: Exception do MessageDlg ('접속 에러 :'+#13+E.Message, mtError, [mbOk], 0);
  end;
End;
0  COMMENTS