Q&A

  • Socket통신에서 ㅠ.ㅠ
* 사용환경 : 델파이5 / Windows 2000

* 에러 메시지 :



Socket 통신을 하고 있는데..

Server는 C로 프로그래밍이 되어 있고 Client는 Delphi로 프로그램이 되어 있슴다...

제가 짜는 프로그램이 Client입니다.

데이타 Type은 Integer와 Char형이 있습니다.



type

TBindPacket = record

MsgType : Integer;

ID : array[0..15] of char;

PassWord : array[0..15] of char;

end;



procedure TForm1.Button1Click(Sender: TObject);

var

i : Integer;

begin

BindPacket.MsgType := 0;

BindPacket.ID := 'aaaaa';

BindPacket.PassWord := 'aaaaa';

ClientSocket.Socket.SendBuf(BindPacket, 40);

end;

이런식으로 레코드를 만들어서 보냅니다.



그런데 문제는 Server에서 Integer를 받는거랑 제가 Integer를 받는데 문제가 좀 있습니다.

좀 알아본바 Server에서 Integer값 1을 보냈을 경우



==> 서버에서 1을 보내면 00 00 00 01을 보내면 받는값이 01 00 00 00 이런식으로 되는것 같은데..

정수형으로 바로 받으면 '1677216'이란 숫자가 들어오거든요..

그래서 이 값을 IntToHex로 변환해 계산을 해서 Int형으로 바꾸니까 '1'이란 숫자가 나와요..

C 와 Delphi의 자료형 구조가 틀려서 인지...

제가 위의 경우에서 BindPacket.MsgType := 160; 이란 숫자를 보낼려면 어떻게 해야 되는지....

위의 예처럼 바뀌어서 가면 Client쪽에서 미리 바꾸어서 보내야 될것 같은데..

어떻게 보내야 되는지 모르겠어요.......

설명이 미비한것 같네요...

고수님들은 어떤상황인지 아시리라 믿고 답변을 기다리겠습니다.





3  COMMENTS
  • Profile
    바다를향해 2001.12.18 02:37
    바이트오더에 대해서 질문을 하셨군요...

    네트워크에서 이기종간의 통신에서는 기종간 바이트오더가 틀린경우가 있져...

    님께서 지금 질문한 경우가 그런경우인데...

    바이트오더를 맞춰주면 되는 아주 간단한 문제에여...

    물론 당근 그러한 함수도 제공이 되구요...

    htons(), ntohs(), htonl(), ntohl() 등등의 함수가 있는데...

    각각의 함수에 대해서는 win32헬프를 찾아 보시면 알수가 있습니다.

    간략히 설명을 하자면 htons에서 'h'는 호스트를 뜻하구요,

    'n'은 네트워크를 뜻하져...'s'는 보낼 데이터형을 의미하는데 Short할때 's'이구여

    그럼 풀이를 하자면 h(호스트)to(에서)n(네트워크바이트오더로 변환해라)s(2바이트짜리를).....대충 이렇게 해석이 되네여....다른 함수들도 의미는 똑같거든여....

    참고로 ntohl에서 맨끝에 'l'자는 Long을 의미 합니다. 당근 4바이트져.....

    그럼 즐코 하세여....^^;;;



    통신초보.. wrote:

    > * 사용환경 : 델파이5 / Windows 2000

    > * 에러 메시지 :

    >

    > Socket 통신을 하고 있는데..

    > Server는 C로 프로그래밍이 되어 있고 Client는 Delphi로 프로그램이 되어 있슴다...

    > 제가 짜는 프로그램이 Client입니다.

    > 데이타 Type은 Integer와 Char형이 있습니다.

    >

    > type

    > TBindPacket = record

    > MsgType : Integer;

    > ID : array[0..15] of char;

    > PassWord : array[0..15] of char;

    > end;

    >

    > procedure TForm1.Button1Click(Sender: TObject);

    > var

    > i : Integer;

    > begin

    > BindPacket.MsgType := 0;

    > BindPacket.ID := 'aaaaa';

    > BindPacket.PassWord := 'aaaaa';

    > ClientSocket.Socket.SendBuf(BindPacket, 40);

    > end;

    > 이런식으로 레코드를 만들어서 보냅니다.

    >

    > 그런데 문제는 Server에서 Integer를 받는거랑 제가 Integer를 받는데 문제가 좀 있습니다.

    > 좀 알아본바 Server에서 Integer값 1을 보냈을 경우

    >

    > ==> 서버에서 1을 보내면 00 00 00 01을 보내면 받는값이 01 00 00 00 이런식으로 되는것 같은데..

    > 정수형으로 바로 받으면 '1677216'이란 숫자가 들어오거든요..

    > 그래서 이 값을 IntToHex로 변환해 계산을 해서 Int형으로 바꾸니까 '1'이란 숫자가 나와요..

    > C 와 Delphi의 자료형 구조가 틀려서 인지...

    > 제가 위의 경우에서 BindPacket.MsgType := 160; 이란 숫자를 보낼려면 어떻게 해야 되는지....

    > 위의 예처럼 바뀌어서 가면 Client쪽에서 미리 바꾸어서 보내야 될것 같은데..

    > 어떻게 보내야 되는지 모르겠어요.......

    > 설명이 미비한것 같네요...

    > 고수님들은 어떤상황인지 아시리라 믿고 답변을 기다리겠습니다.

    >

    >

  • Profile
    이경문 2001.12.12 03:13
    이는 언어의 특성이기보다는 CPU의 특성입니다.

    ARM계열은 Big Endian을 사용하고

    Intel 계열은 Little Endian을 사용하기 때문입니다.



    Little Endian계열에서 1을 나타낼 때

    host byte order는 01 00 00 00 이고

    network byte order는 00 00 00 01 입니다.

    네트워크로 정수를 송수신할 때는 network byte order로 변환해 주는 것이 바람직합니다.



    htonl (host to network, long)

    ntons (host to nwtwork, short)

    ntohl (network to host, long)

    ntohs (nwtwork to host, short)



    Interl CPU에서는 송신할 때 htonl을 사용해서 변환하고

    수신할 때 ntohl를 사용해서 변환해 보시기 바랍니다.





    통신초보.. wrote:

    > * 사용환경 : 델파이5 / Windows 2000

    > * 에러 메시지 :

    >

    > Socket 통신을 하고 있는데..

    > Server는 C로 프로그래밍이 되어 있고 Client는 Delphi로 프로그램이 되어 있슴다...

    > 제가 짜는 프로그램이 Client입니다.

    > 데이타 Type은 Integer와 Char형이 있습니다.

    >

    > type

    > TBindPacket = record

    > MsgType : Integer;

    > ID : array[0..15] of char;

    > PassWord : array[0..15] of char;

    > end;

    >

    > procedure TForm1.Button1Click(Sender: TObject);

    > var

    > i : Integer;

    > begin

    > BindPacket.MsgType := 0;

    > BindPacket.ID := 'aaaaa';

    > BindPacket.PassWord := 'aaaaa';

    > ClientSocket.Socket.SendBuf(BindPacket, 40);

    > end;

    > 이런식으로 레코드를 만들어서 보냅니다.

    >

    > 그런데 문제는 Server에서 Integer를 받는거랑 제가 Integer를 받는데 문제가 좀 있습니다.

    > 좀 알아본바 Server에서 Integer값 1을 보냈을 경우

    >

    > ==> 서버에서 1을 보내면 00 00 00 01을 보내면 받는값이 01 00 00 00 이런식으로 되는것 같은데..

    > 정수형으로 바로 받으면 '1677216'이란 숫자가 들어오거든요..

    > 그래서 이 값을 IntToHex로 변환해 계산을 해서 Int형으로 바꾸니까 '1'이란 숫자가 나와요..

    > C 와 Delphi의 자료형 구조가 틀려서 인지...

    > 제가 위의 경우에서 BindPacket.MsgType := 160; 이란 숫자를 보낼려면 어떻게 해야 되는지....

    > 위의 예처럼 바뀌어서 가면 Client쪽에서 미리 바꾸어서 보내야 될것 같은데..

    > 어떻게 보내야 되는지 모르겠어요.......

    > 설명이 미비한것 같네요...

    > 고수님들은 어떤상황인지 아시리라 믿고 답변을 기다리겠습니다.

    >

    >

  • Profile
    kuma 2001.12.12 02:35
    서버랑 구조체만 같다면 문제가 되지 않는데요...

    저는 버퍼에 담고 그버퍼를 보내고...

    버퍼에 받고 그버퍼를 구조체로 복사하는 방식을 쓰는데요...

    <보낼때>

    var

    i : Integer;

    acBuf: array of char;

    BindPacket: TBindPacket;

    BP: TBindPacket;

    begin

    BindPacket.MsgType := 1;

    BindPacket.ID := 'aaaaa';

    BindPacket.PassWord := 'aaaaa';



    SetLength( acBuf, sizeof( TBindPacket ) );

    CopyMemory( acBuf, @BindPacket, sizeof( TBindPacket ) );



    //...Send( acBuf, sizeof( TBindPack ) ); ....

    end;



    <받을때>

    var

    BP: TBindPacket;

    // acBuf: array [0..1024] of char;

    begin

    // recv( acBuf, sizeof( TBinPack ) );.....

    CopyMemory( @BP, acBuf, sizeof( TBindPacket ) );



    결론으로 구조체의 정렬방식 순서에 따라 틀리지 같아요.....

    패킷정렬을 했나 안했나....



    답변이