C와 JAVA 구조체 소켓 통신 卒業プロジェクト

c에서 넘겨주는 구조체정보는 java에서는 구조체가 없기때문에

c로부터 전송되는 바이트 데이터를 java에서 다시 재가공(?) 시켜줄 필요가 있다. 

하지만 그 과정에서 조심하지 않으면 문자가 깨지거나, 엉뚱한 숫자 값이 나올 수 있다.

여하튼 그 문제를 해결하기 위한 방법을 알아 보자!



일단 c에서는 

#pragma pack(1)

위와 같은 전처리기를 선언해줄 필요가 있는데, 이는 구조체의 정확한 메모리값을 얻기 위함이다.

아무튼 다음과 같은 총 16바이트의 구조체를 JAVA로 전송해보자.


typedef struct testStruct
{
char name[10]; //10byte
int price; //4byte
short cnt; //2byte
} testStruct;



//전송부분
testStruct t;

//t.price = htonl(1123);
//t.cnt = htons(100);
t.price = 1123;
t.cnt = 100;
initBuff(t.name);
sprintf(t.name, "%s", "kim");
send(s, (char*)&t, 16, 0);

여기서 price와 cnt에 그냥 1123과 100을 대입하는 것과 htonl()과 htons()을 이용하여 값을 대입하는 방법이 있는데,

그냥 값을 대입하였을 경우, 자바에서 byte 배열을 int로 변환하였을 때 전혀 엉뚱한 값이 나온다 이는 바이트 순서의

문제인듯하다. 따라서 htonl과 htons를 사용하여 네트워크 바이트 순서(big - endian)로 바꾸어 대입하고 이를

send()함수로 보내주면 c에서는 문제 없이 전송이 된다.



다음으로 java에서는
Class testStruct{
  String name;
  int price;
  short cnt;
}


//수신 부분

byte buff[] = new byte[16];
testStruct data = new testStruct();
int readSize;
while((readSize = is.read(buff)) != -1)
{
//name부분
byte[] tempArr = new byte[10];
System.arraycopy(buff, 0, tempArr, 0, 10);
data.name = new String(tempArr);
//price부분
tempArr = new byte[4];
System.arraycopy(buff, 10, tempArr, 0, 4);
data.price = getInt(tempArr);
//cnt부분
tempArr = new byte[2];
System.arraycopy(buff, 14, tempArr, 0, 2);
data.cnt = getShort(tempArr);
}

c에서 보낸 구조체를 클래스로 대신하여 정의해놓고 c로부터 수신된 바이트 데이터를 buff 배열에 받아두고
c에서 자료의 크기별로 잘라서 문자는 String클래스의 생성자로 바로 변환해주며(한글에 대해서는 잘 모르겠네요)

int나 short등 숫자데이터 관련해서는 따로 변환해주는 코드를 참고 해야하는 듯 하다

제가 사용한 변환 코드입니다. 

- byte[] to int

public int getInt(byte[] bt){
int temp = 0;
int[] bt2 = new int[4];
for(int i=0; i<4; i++)
{
bt2[i] = bt[i] < 0 ? ((Byte.MAX_VALUE + 1) * 2) + bt[i] : bt[i];
temp |= (bt2[i] << (8*(3-i)));
}
return temp;
}


- byte[] to short

public int getShort(byte[] bt){
short temp = 0;
short[] bt2 = new short[2];
for(int i=0; i<2; i++)
{
bt2[i] = bt[i] < 0 ? (short)((Byte.MAX_VALUE + 1) * 2 + bt[i]) : bt[i];
temp |= bt2[i] << 8*(1-i);
}
return temp;
}

1 2 3 4 5 6 7 8 9 10 다음