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;