|
먼저 간단하게 정리해 보겠습니다.
- struct 잡은 데이터를 소켓을 통해 서버에서 클라이언트로 전송한다.
- 서버에서 보낸 데이터를 클라이언트의 struct 로 받아서 확인한다.
- 서버, 클라이언트의 struct는 동일하다.
위의 3가지 라고 생각합니다 만은....
제 경험상으로는 약간 이상한 점을 발견했다고 해야 할까요?
그것을 설명하자면,
소켓을 통해 서버든, 클라이언트든 서로 소켓으로 전송되는 것은 무조건 문자로 받습니다.
(정확하게는 말하자면 아스키 코드 16진수 지만)
그것을 int 형식의 변수를 전송하든, String 형태든 간에 일단 소켓으로 보낸 데이터는
랜선을 통해서 오면 무조건 문자형태로 들어옵니다.
제가 보통 사용하는 방법은 전송이 필요한 부분은 숫자든 문자든 무조건 char test[size]; 크기로 잡아서
사용합니다. 예를 들어
struct MY_STRUCT
{
char * a;
char b[100];
};
MY_STRUCT *PMY_STRUCT;
이런식으로 작성하여, 전송 시에는 전송방식은 같지만,
아래의 코드는 상당히 주의해야할 부분이 있습니다.
struct MY_STRUCT
{
int a;
char b[100];
};
MY_STRUCT *PMY_STRUCT;
로 데이터가 잡혀 있다고 치면,
a = 1 이라는 가정하에, 전송이 되었다고 칩시다.
그럼 받는 쪽에서는 문자나 숫자 1이 아닌 아스키 코드 0x01이 됩니다.
왜냐, 전송되는 시점에서 프로그래머 의도가 중요합니다.
10진수 1(16진수 31)을 받을 것인가 아니면 16진수 0x01을 받을 것인가를 분명히 해줘야 합니다.
실제 int 1을 전송하면 받는 쪽에서는 0x01을 받습니다.
문자 1을 전송하면 받는 쪽에서는 0x31을 받습니다.
하고자하는 것이 받는 쪽에서도 보내는 쪽에서 와 같은 숫자를 받고 싶으시다면
받는 쪽에서 보는 것은 16진수로 계산된 문자라는 사실입니다.
16진수 0x31을 전송을 해야 받는 쪽에서 '1'이 라는 것을 인식할 수 있습니다.
1을 받기위해서는 int의 값을 31로 해줘야합니다.
(자세한건 아스키코드 테이블 참조)
그리고
char b[100]; 에 관한 문제 입니다.
지금은 하나의 배열만 사용하였습니다. 하지만, 하나가 더 생성된다면
char b[100];
char c[100];
만약 b의 문자가 99자까지면 정상적으로 데이터가 입력됩니다
하지만 b의 문자가 100자가 된다면, 다음에 있는 c의 데이터 문자는 b 배열의 종료 부분이 없기
때문에 b에 배열 주소에 바로 뒤에 붙어 c의 문자 데이터가 아닌 b의 문자데이터가 되어버립니다.
(ㅡㅡ; 머리 나빠 설명하기 힘듬)
이것의 원인은 당연히 b의 데이터에 종료문자가 없기때문입니다.
해결방법은 당연히 넉넉하게 배열 잡거나, 정확하게 범위를 계산해서 종료문자를 포함해서 잡아야 겠죠...
아니면 b[101] 로 잡아 종료문자가 들어갈 수 있도록 하거나....
모든 것의 데이터가 이상이 없을 경우 받는 쪽도 똑같이 받으면 됩니다.
쓸데없이 긴글이지만 조금이라도 도움이 되었으면 하는 바램에서 적어보았습니다.
구리구리 님이 쓰신 글 :
: 패킷을 구조체로 전송할 수 있다고 하는데요
: char형으로 변환을 해서 보내야 제대로 간다고 하더라구요
: 그래서 구조체안의 변수들에 값을 채워서 아래처럼 보냈는데요
: send(sock, (const char *)pMyStruct, cch, 0);
: 데이터를 받아보니 'd'라는 값이 오더라고요
: 보내는 곳에서 디버깅해서 보니 (const char *)pMyStruct값이 'd'로 나오고요
: 왜 이렇게 나오는지 모르겠네요
: 데이터를 받는 곳에서도 보내는 곳에서와 같은 구조체가 선언 되어있으면
: 값을 받아서 쓸수 있나요? 어떻게 쓰면되죠?
: 자세히 좀 알려주세요 ㅠ,.ㅠ
:
|