Q&A

  • Indy 9 ReadBuffer, WriteBuffer 그리고 포인터 구조체

 

학교에서 네트워크 수업하다가

 

간단한 프로그램 만들어 보려고 Indy 9 컴포넌트를 사용해보게 되었어요.

 

포인터 구조체에 패킷을 넣고, 서버에서 받아서 처리하기 위해서 Flag 를 넣고 Data를 보내도록~

 

그런데 포인터 구조체를 보내고 받고 하는 부분이 잘 안되서 도움을 받을수 있을까 해서 이렇게 글을 올려 봅니다.

 

 

포인터 구조체는 다음과 같이 코딩햇습니다.

 

type
  TSocketDataHeader = record
    Flag : Word;    //플래그
    Size : Integer; //데이터 사이즈
  end;
  TSocketData = record
    Header : TSocketDataheader;  //헤더정보
    Data   : Pointer;            //데이터
end;
pSocketData = ^TSocketData;

 

메시지를 보내는 클라이언트 녀석을 요렇게 했죠

 

procedure TForm1.btnConnectClick(Sender: TObject);
var
  pPacket : pSocketData;
  pData   : ^string;
  Data    : string;
begin

  {포인터 구조체 활당}
  New(pPacket);

 

  {보낼 메시지}
  Data := 'Client Message';
  pData := @Data;

  pPacket^.Header.Flag := 0;
  pPacket^.Data        := pData;
  ppacket^.Header.Size := Length(Data);

 

  {서버에 접속}
  IdTCPClient1.Connect;

  {서버에 메시지 보내기}
  IdTCPClient1.WriteBuffer(pPacket^, SizeOf(pPacket), True); //<< 안됨

  OutputDebugString(PCHAR(Format('%d', [SizeOf(pPacket)])));

 

  {포인터 구조체 메모리 해제}
  Dispose(pPacket);

end;

 

서버에서 메시지를 받을 때 처리는 다음과 같이 했습니다.

 

procedure TForm1.IdTCPServer1Execute(AThread: TIdPeerThread);
var ClientInfo    :TClientInfo;
    MessageClient : string;
    pPacket : pSocketData;
begin
  ClientInfo := Pointer(AThread.Data);
  if ClientInfo = nil then Exit;

  {포인터 구조체 초기화}
  New(pPacket);

  try
    {패킷의 헤더 사이즈를 읽는다}
    AThread.Connection.Readbuffer(pPacket^.Header, SizeOf(pPacket^.Header));

    {헤더 사이즈가 있을경우}
    if pPacket^.Header.Size > 0 then
    begin
      {받을 데이터의 크기만큼 메모리 활당}
      GetMem(pPacket^.Data, pPacket^.Header.Size);
     
      {데이터를 읽는다}
      AThread.Connection.ReadBuffer(ppacket^.Data^, ppacket^.Header.Size);
    end;

    {포인터형 변수를 텍스트로 읽는다}
    MessageClient := DataToText(pPacket^.Data, pPacket^.Header.Size);

    {메시지 출력}
    memo1.Lines.Add(MessageClient);

    {플래그별 메소드 실행}
    case pPacket^.Header.Flag of
      0 : Memo1.Lines.Add('Client Flag : 0');
      1 : Memo1.Lines.Add('Client Flag : 1');
    end;

  except
    {이상한 문자가 오면 정지}
    AThread.Stop;
  end;

  {포인터 구조체 해제}
  Dispose(pPacket);

end;

 

 

코드상에선 에러없이 컴파일되고, 실행되 잘됩니다.

 

커넥선, 디스커넥션 메시지도 잘 처리 되는데, 이상하게 WriteBuffer 와 ReadBuffer가 메시지 처리가 안되네요.

 

첨부파일에 소스코드 올립니다.

 

OutPutBin : ../

 

2  COMMENTS
  • Profile
    zeliard 2011.05.23 21:56

    포인터를 보내면 안됩니다. 포인터의 내용을 보내야죠... 포인터는 현재 프로그램내에서만 유효한 값입니다.
    또한 SizeOf(포인터)는 항상 4입니다. (SizeOf(pPacket) ==4)

    서버에서 받을때처럼 두번에 나눠서 보내시던가 구조체를 포인터없이 데이터만 담을수 있도록 변경하세요. (TSocketData.Data가 포인터입니다.)

  • Profile
    karl 2011.05.24 01:59

    답변감사드립니다. 

     

    다음과 같이 두번 전송하여 해결하였습니다.

     

     WriteBuffer(구조체^. 헤더, SizeOf(구조체원형));  //헤더정보 보내기 (플래그, 데이터의 길이)
     WriteBuffer(구조체^.데이터^,  데이터길이);          //데이터보내기 (포인터값, 포인터값의 길이)

     

    • 심즈
    • 2011.07.15 00:57
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 구창민
      2011.08.11 22:24
      project1.dof 파일이 있는 위치를 열어서 확인해보세요.. 디렉토리가 읽기 전용으로 되어 있다거나, 파일이...
    • 심즈
      2011.08.25 00:27
      답변 감사합니다.. 확인 해 볼게요..^^
    • 수원성
      2011.07.26 18:34
      QR Code가 많이 사용 (서적,스마트 폰 사용)2D Barcode VCL Componentshttp://www.han-soft.com/barcode2d....
    • Jins_lee
      2011.08.03 19:54
      델파이 3에서도 출력 가능했습니다. 이미지 형태로 만들어서 넣었던 걸로 기억합니다. 
    • 심즈
    • 2011.07.02 20:10
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 심즈
      2011.07.03 07:37
      Form의 오브젝트 인스펙터에서 HorzScrollBar 속성 의 Tracking 을 True 로 하니 웹브라우저도 ...
    • 빡스
    • 2011.06.25 04:37
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 소나기
      2011.06.25 16:38
      책이 거의 전무하다 싶네요.인터넷 서점을 보시면 중고책을 팔고 있습니다. 그런데서 한번 찾아 보시고.시...
    • 수인아빠
      2011.06.27 17:30
      7월중에 데브기어에서 책이 출간된다는 소식이 있긴 합니다.....
    • zeliard
      2011.06.17 07:00
      TScrollBox에 TImage를 넣어서 써보세요.
    • anonymous
      2011.06.17 08:14
      http://www.delphi.co.kr/?mid=lecture&document_srl=213987
    • 심즈
    • 2011.06.11 22:12
    • 6 COMMENTS
    • /
    • 0 LIKES
    • zeliard
      2011.06.12 17:02
      장비가 PC로 데이터를 능동적으로 보내면 UDPServer 컴포넌트를 사용하는것이 맞는데... PC에서 장비의 데...
    • 심즈
      2011.06.12 19:35
      최용일님 댓글 감사합니다.. 제 생각에는 UDPClient컴포넌트를 사용해서 장비의 Data를 읽는 방법이 ...
    • zeliard
      2011.06.13 20:14
      접속이 성공했다면 절반 이상은 하신겁니다. 데이터 읽는것은 장비의 매뉴얼을보세요. 장비의 프로토콜에 ...
    • 심즈
      2011.06.14 05:57
      최용일님 정성스러운 답변 감사합니다^^ 제가 자꾸 글을 올려서 죄송합니다만.. UDPClient 컴포넌트로...
    • zeliard
      2011.06.14 19:49
      인디 예제를 보세요.     IdUDPClient1.Host := '192.168.0.10';  // Server IP address &n...
    • 심즈
      2011.07.02 20:11
      답변 감사합니다^^
    • 구창민
      2011.06.11 02:09
      API 가 존재합니다. 아래 함수를 사용해 보세요. function _GetLogonUserName : String;var&n...
    • 누구를대신해
      2012.06.12 02:09
      그런방법이
    • zeliard
      2011.06.01 23:30
      병렬처리라... 걱정하실 필요가 없습니다. 서버와 여러 클라이언트들과의 커넥션이 하나라는것은 존재할 수...
    • 우당탕탕
      2011.06.01 23:42
      답변 감사합니다.   제가 글을 잘못 올린듯 한데요.   서버와 클라이언트가 각각 하나입니다. 측...
    • 이정욱
      2011.06.02 00:17
      Que 를 만들어서 사용하세요.그리고 처리 루틴을 원하시는 쓰레드 수 만큼 생성 후, 각 쓰레드에서 Que에서...
    • zeliard
      2011.06.02 01:34
      정욱님 말씀이 정답입니다.
    • 은우
    • 2011.05.31 03:15
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 홍성락
      2011.05.31 03:52
      아주예전에 올렸던건데요. :   는 선언문(~이다), GOTO문의 레벨명에 사용도 합니다.:= &nb...
    • 은우
      2011.06.01 17:43
      감사합니다.
    • 완전한사랑
      2011.05.31 18:58
      자문 자답을 하게 되는 군요,,, ^^ procedure Copy_File(FromFile, ToFile: String); var FD...
    • 소프트테크
      2011.05.27 16:22
      짚어봐야 할 사항 들입니다.1. 통신포트를 설정하고 , 통신포트를 열었는가?2. 통신포트의 설정내용은 정확...
    • 소나기
      2011.05.27 19:28
      음 스크롤 되고 있는 상황인걸 보니   데이터는 들어 오고 있네요.   들어 오는 데이터가 아스...
    • 초보델피언
      2011.05.25 20:48
      정확히 어떤 필드가 숫자형인지는 모르지만 ''' 를 ' 만 사용하면 되지 않을까요?
    • 완전한사랑
      2011.05.25 21:59
      답변 감사드립니다..  제가 너무 설명을 못한거 같네요. .ㅠ.ㅠSqlData[1]~[25]까지 전부 문자형으...
    • karl
      2011.05.26 19:10
        Query.SQL.Clear;  Query.SQL.Add('INSERT INTO 테이블 (컬럼1,  컬럼2, 컬럼3) &nb...
    • 완전한사랑
      2011.05.27 19:18
      답변 감사합니다.. 우선 여러 가지 방법으로 함 해보려고 합니다..말씀 하신 내용 참고해서 작업해 볼께...
    • karl
    • 2011.05.24 02:08
    • 4 COMMENTS
    • /
    • 0 LIKES
    • zeliard
      2011.05.24 17:26
      TIdTCPClient.ReadTimeout을 설정해보세요.
    • karl
      2011.05.24 18:36
      ReadTimeout 을 5 ~ 5000 까지줘봤는데, 커넥트 하자마자 ReadTimeError 가 나오네요.
    • zeliard
      2011.05.25 15:14
      데이터가 없으면 예외가 발생합니다. 예외처리하시고 데이터가 올때까지 기다리세요.
    • karl
      2011.05.25 18:31
      아... 그런거였군요! 감사합니다!! ^^
    • karl
    • 2011.05.23 20:02
    • 2 COMMENTS
    • /
    • 0 LIKES
    • zeliard
      2011.05.23 21:56
      포인터를 보내면 안됩니다. 포인터의 내용을 보내야죠... 포인터는 현재 프로그램내에서만 유효한 값입니다...
    • karl
      2011.05.24 01:59
      답변감사드립니다.    다음과 같이 두번 전송하여 해결하였습니다.    WriteBuff...
  • profile karl
    2011/05/23 20:02
  • Views4975
    Likes0
    Comments2
    Reports0
  • Tag List
  • 목록으로