> JAVA > Java에서 C 모듈과의 소켓통신시 유의사항

Java에서 C 모듈과의 소켓통신시 유의사항

잘 알다시피 자바는 JVM 플랫폼 위에서 연동되며 소켓통신등의 바이트 전송시 byte order 가 BIG_ENDIAN 이다. 하지만 C 처럼 실행파일이 만들어지는 경우는 해당 플랫폼에 따라서(좀 더 정확히는 CPU 종류에 따라서) byte order 가 달라진다.intel, alpha 와 같은 경우에는 LITTLE_ENDIAN이며, sun sparc, mac os, 그리고 JVM 같은 경우에는 BIG_ENDIAN 이다.

c 의 경우 플랫폼별로 1 바이트를 이루는 크기가 다른데 이는 보통 /usr/include/machine 의 limits.h 와 같은 곳에 CHAR_BIT 이라는 이름으로 정의되어 있으며 byte order 는 /usr/include/macine 에 endian.h 와 같은 형태로 되어 있다.
다음은 intel 용 freebsd 의 endian.h 의 내용중 일부이다.

#define LITTLE_ENDIAN   1234    /* LSB first: i386, vax */
#define BIG_ENDIAN      4321    /* MSB first: 68000, ibm, net */
#define PDP_ENDIAN      3412    /* LSB first in word, MSW first in long */
#define BYTE_ORDER      LITTLE_ENDIAN

16bit OS 의 경우 한번에 2바이트씩 전송한다고 볼 수 있으므로(안그런 경우도 있지만) 만약 32bit 의 자료형을 전송하게 되면 이를 16bit 찍 잘라서 전송하게 되는데, 이때부터 byte order 의 문제가 발생한다.

전송해야 하는 4 byte 가 1 2 3 4 와 같이 있다고 할때, big_endian 은 12   34  이렇게 전송을 하고, little_endian 은 34   12  이렇게 나눠서 전송을 한다고 생각하면 쉬울 것이다.

따라서 전송하는 쪽의 내용과 받는쪽의 내용이 4 byte를 기준으로 상위 2byte 와 하위 2byte가 서로 상이하게 될 수가 있다.

이는 굳이 자바와 C 사이의 소켓통신뿐만이 아니라 이기종간 C와 C사이 통신에서는 언제든지 발생할 수 있는 상황이다.

해결책은?

별다른건 없다. 자바쪽에서는 보낼때 BIG_ENDIAN 으로 전송하고, 상대방쪽이 자바모듈이 아닐 경우는 플랫폼 정보를 얻은 다음 전송되어 온 바이트를 적절히 바꿔주면 된다.

C 의 경우는 endian.h 의 정보에 따라서 코딩을 해주면 된다.

if (  BYTE_ORDER == BIG_ENDIAN )
   // 1234 로 전송해
else if ( BYTE_ORDER == LITTLE_ENDIAN )
  // 4321 로 전송해

이런식으로 하면 소스수준의 이식성을 높일 수가 있을 뿐만 아니라 다른 시스템과의 소켓통신 등에도 유용하게 사용할 수 있다.
이런때 써먹기 위한 함수가 몇개 있는데(물론 c에서..) htonl, htons, ntohl, ntohs 등이 그것이다.
각각의 사용법은 알아서 발견하는 기쁨을 누려보도록 하자.

카테고리:JAVA
  1. 댓글이 없습니다.
  1. No trackbacks yet.

댓글 남기기