Q&A

  • [질문] UDP 통신에 대한 질문
TCP와 UDP 통신을 시도하고 있는데 보통의 프로그램과는 특성이 많이 다르다는 느낌입니다.
프로그램의 동작이 예상대로 되지 않는 경우가 많네요.(물론 실력이 부족해서 그렇겠지만)
UDP 통신 중에 안풀리는 문제가 있어서 질문드립니다.

데이터를 연속으로 보내기 위해서 Indy UDP Client를 사용했습니다. 수신측은 Indy UDP Server를 사용했고요.

1. Client : 시작 버튼을 누르면 초기 접속을 위해 RQST로 시작하는 메시지를 보냅니다.
2. Server : OnUDPRead Event에서 RPLY로 시작되는 문자를 보냅니다(응답)
3. Client : Server의 RPLY 응답을 받고 SGNL로 시작하는 신호를 보내는 무한 Loop를 시작합니다.

4. Client : 정지 버튼을 누르면 송신이 중지되고 UDPClient.Active := false 가 됩니다.

여기서 이상한 점이 두가지 있는데

하나는 시작버튼을 누르면 3~4초 있다가 RPLY 응답을 받고 송신 무한 Loop를 시작합니다.

두번째는 중지 버튼을 누르면 중지되는데 다시 시작버튼을 누르면 송신 응답은 되는 듯한데 송신 무한Loop가 되지 않습니다.
    이때 중지 버튼을 2~3번 누르고 다시 시작버튼을 누르면 송신Loop가 동작합니다.(2~3번이라는 것도 일정하지가 않습니다)

원인을 알려주시면 감사하겠습니다.

<송신 시작 버튼>
procedure TClientFrmMain.BitBtn3Click(Sender: TObject);
var
    AMessage, BMessage : string;
begin
    UDPClient.Active := true;
    try
      AMessage := 'RQST'+':'+'&'+':'+'&'+':'+ClientIP;
      UDPClient.Send(AMessage);
      Memo1.Lines.Add ('Sended first : '+AMessage );

      BMessage := UDPClient.ReceiveString();
      Memo1.Lines.Add ('Readed first: '+BMessage );
    except
      on E: Exception do MessageDlg ('Error while connecting:'+#13+E.Message,
             mtError, [mbOk], 0);
    end;

    SendingLoop; // -> 송신 무한 Loop
end;

<서버 수신부>
procedure TServerFrmMain.UDPServerUDPRead(Sender: TObject; AData: TStream;
  ABinding: TIdSocketHandle);
var
  DataStringStream : TStringStream;
  CMessage : string;
  Header, HexaHigh, HexaLow, ClientIP, Reply : string;
  iClientCode : integer;
begin
  DataStringStream := TStringStream.Create('');
  try
    DataStringStream.CopyFrom(AData, AData.Size);
    CMessage := DataStringStream.DataString;

    DataAnalyze(CMessage, Header, HexaHigh, HexaLow, ClientIP);

    if Header = 'RQST' then begin
      Protocol.Lines.Add(TimeToStr(Time)+' : '+CMessage+' from '
        + ABinding.PeerIP+' on Port  '+IntToStr(ABinding.PeerPort));
      Reply := 'RPLY'+' from '+ UDPServer.LocalName + ' to '+ABinding.PeerIP;
      ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, Reply[1], Length(Reply) );
      Memo1.Lines.Add('Sended : '+Reply);
    end
    else if Header = 'SGNL' then begin
      DataProcess(HexaHigh, HexaLow, iClientCode);  //Data 처리부
    end
    else;

  finally
    DataStringStream.Free;
  end;
end;


<송신 무한 Loop>
procedure TClientFrmMain.SendingLoop;
var
  BMessage : string;
  ii,jj : integer;
  HexaHigh, HexaLow : string;
begin
  While not IsCancel do begin
    Application.ProcessMessages;
      BMessage := 'SGNL'+':'+HexaHigh+':'+HexaLow+':'+ClientIP;
      UDPClient.Send(BMessage);
      IncomingMessages.Lines.Add ('Sended : ' +BMessage);
  end; //while
end;

<송신 정지 버튼>
procedure TClientFrmMain.BitBtn4Click(Sender: TObject);
begin
    IsCancel := Not IsCancel;

    UDPClient.Active := false;
end;
3  COMMENTS
  • Profile
    최용일 2010.06.16 23:07
    다른것은 모르겠구 송신 무한루프가 두번째가 안되는 것은 정상적인 동작인데요...
    IsCancel이 첫번째 중지될때 True로 바뀌고 끝이네요...
    무한 루프를 정상적으로 동작시키실려면 송신시작번튼부분에서 루프돌기 전에 IsCancel을 False로 바꿔주셔야 정상적으로 돌겠죠...
  • Profile
    최용일 2010.06.16 23:10
    첫번째 3-4초 후에 응답을 받는 부분은 실제로 서버에서 늦게 응답을 하는가 아님 클라이언트에서 늦게 반응하는가를 확인해보셔야 겠는데요...
    Ethereal이나 WireShark로 패킷을 캡춰해서 어느쪽 문제인가부터 확인을 해보세요.
  • Profile
    이용벽 2010.06.17 00:11
    감사합니다. 두번째 문제는 그런 원인이 있었군요. 해결되었습니다.

    첫번째 문제는 주신 힌트를 기반으로 더 파고들어 가야겠군요.

    • phono
      2010.06.20 20:08
      Lines.String.text 로 해보셨나요?
    • 통통만두
      2010.11.07 10:52
      흠.. 그냥 간단하게.. try Memo.Lines.BeginUpdate; finally Memo.Lines.EndUpdate; end; ...
    • 델코이
    • 2010.06.18 20:59
    • 5 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2010.06.19 02:16
      그런 방법이 있을리가 있나요... 포기하세요.
    • 땅콩맨
      2010.06.19 06:17
      컴퓨터 학문중 '역공학(Reverse Engineering)' 이라는 것이 있습니다. 역공학을 공부하기 위해서는 Hex ...
    • 폐기처분中
      2010.06.24 22:49
      리버스 엔지니어링을 하면 어느 정도의 알고리즘은 뽑아 낼 수 있겠지만... 바이너리 파일을 완벽히 코...
    • 이규하
      2010.06.25 12:53
      혹시나 하고 찾아 봤는데. 아래의 싸이트를 참고 해 보세요. http://delphi.about.com/od/devutili...
    • 땅콩맨
      2010.07.04 04:53
      흠... 원본소스를 재생하는것은 있을수 없다라고 적혀있네요.. 폐기처분中님이 말씀하신 것처럼 처음부...
    • 최용일
      2010.06.17 21:14
      TStringGrid, TDBGrid
    • 이승규
      2010.06.17 23:56
      음~~ 어디서 구할수 있나요 ^^ 7.0버젼인뎅
    • 살며배우며
      2010.06.23 08:20
      TStringGrid은 Additional에 , TDBGrid는 DataControl 텝에 있습니다.
    • 아폴론
    • 2010.06.18 00:28
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 사우리
    • 2010.06.18 00:05
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 이용벽
    • 2010.06.16 22:51
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2010.06.16 23:07
      다른것은 모르겠구 송신 무한루프가 두번째가 안되는 것은 정상적인 동작인데요... IsCancel이 첫번째 ...
    • 최용일
      2010.06.16 23:10
      첫번째 3-4초 후에 응답을 받는 부분은 실제로 서버에서 늦게 응답을 하는가 아님 클라이언트에서 늦게 ...
    • 이용벽
      2010.06.17 00:11
      감사합니다. 두번째 문제는 그런 원인이 있었군요. 해결되었습니다. 첫번째 문제는 주신 힌트를 기반...
    • 아폴론
    • 2010.06.16 20:22
    • 5 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2010.06.16 21:27
      BDE대신에 ODBC나 ADO를 쓰면 크게 안 고치셔도 될 것 같은데요...
    • phono
      2010.06.16 22:20
      용일님 의견에 덧 붙히자면... dbExpress는 단방향 데이타 셋 입니다. 즉 DataSet을 스크롤시 next...
    • 이용벽
      2010.06.16 22:47
      InstallAware를 쓰려다가 BDE에 걸려서 안되고 있는데 ODBC나 ADO를 쓰면 InstallAware에서 문제없나요?
    • 최용일
      2010.06.17 04:32
      ODBC, ADO 다 지원하는 것으로 알고 있는데요...
    • 가을바람
      2010.06.19 23:28
      문득 옛날 회사에서 bde안쓰고 dbExpress썼다고 犬ㅈㄹ하던 한 인간이 생각나네요.. ㅎㅎ
    • 김민수
    • 2010.06.14 22:33
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2010.06.14 23:42
      StringGrid1.Row := StringGrid1.Row + 1; StringGrid1.Cells[StringGrid1.Row, 0] := '추가된 첫번째 ...
    • 최용일
      2010.06.14 21:37
      FindFirst/FindNext/FindClose함수로 폴더의 파일 목록을 읽어와서 그 수많큼 루프를 돌려서 업로드하는 ...
    • 김민수
      2010.06.14 22:08
      힌트 감사합니다! 큰 도움이 되었습니다.
    • 초빼이
    • 2010.06.14 06:35
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2010.06.14 10:06
      TFrm_Schedule생성할 때 Owner로 Self 즉, TFrm_Preview를 넣어주셨으니까 특정버튼의 OnClick이벤트에서...
    • 아폴론
    • 2010.06.12 23:07
    • 2 COMMENTS
    • /
    • 0 LIKES
    • phono
      2010.06.14 20:16
      일단 BDE는 64bit 지원이 안되는 것으로 알고 있구요.. 그래서 저는 BDE 문제 때문에 5~6년 전 부터 ...
    • 박홍재
      2010.06.15 13:05
      Del 2005를 사용하고 있고 예전 Del 7 인스톨러에서 만든 Setup Program을 돌려서 64bit 7에 설치를 했습...
    • 홍성락
      2010.06.12 00:48
      어! 이런게 있었군요. 주의해야겠네요. 그런데 일반적으로 화면 갭쳐시 PaintTo등의 단순한 함수보다도 ...
    • 미스터몽키
      2010.06.15 05:37
      이런 쉬운 방법이 있었군요 홍성락님 정말 감사합니다.
    • 김현철
    • 2010.06.10 19:57
    • 0 COMMENTS
    • /
    • 0 LIKES
    • 이윤도
      2010.06.10 23:28
      StrToIntDef 이나 StrToFloatDef 를 참조하세요!! ex) StrToIntDef(str, 0) <- Str이 정상적인 숫자...
    • 박홍재
      2010.06.09 12:53
      일단 질문이 조금 이해가 되지 않아서.. 이미 포스시스템에서 입장객을 Check 하고 있다면 이미 Barcode...
    • 이규하
      2010.06.09 16:34
      바코드 리더를 RS-232C 타입으로 하시구요 ... RS-232C Component 하나 올리시고 ... 데이터 들어 올...
    • 최선호
      2010.06.09 22:36
      두분 관심 가져 주셔서 감사드립니다. 이규하님 말씀하신 데로 한번 해봐야 겠습니다.. 그리고 박홍재...
    • 박홍재
      2010.06.10 08:51
      RS-232 바코드 리더의 경우 프로그램에서 신호를 주어야 읽을 수 있습니다. 따라서 실행하는 프로그램에...
    • 박홍재
      2010.06.10 08:56
      Scanner의 메뉴얼을 살펴 보시면 Data을 읽을때 앞이니 뒤쪽에 지정하는 문자를 Default로 출력되도록 만...
    • 최선호
      2010.06.11 00:03
      친절하고 자세한 설명 감사드립니다..