소켓프로그래밍 - 구조체 보내기...
글쓴이: kernelbomb / 작성시간: 월, 2004/03/29 - 4:30오후
안녕하세요?
UNP를 보고 공부하고 있는데요.
숫자의 경우 UNP에선 문자로 만들어 보내던지 빅엔디언으로 넷똑에
보내고 받을 때는 호스트에 바이트오더에 맞게 받으면 된다고 하는데요.
아래 소스를 실행시키면 이상하게 동작합니다.
서버측 보내는 프로그램
void str_echo(int sockfd) { ssize_t n; struct args args; struct result result; for (;;) { if ((n = readline(sockfd, &args, sizeof(args))) == 0) return; printf("SERVER : arg1 = %ld\t arg2 = %ld\n", ntohl(args.arg1), ntohl(args.arg2)); result.sum = htonl(args.arg1 + args.arg2); writen(sockfd, &result, sizeof(result)); } }
클라이언트의 보내는 프로그램
void str_cli(FILE *fp, int sockfd) { char sendline[MAXLINE], recvline[MAXLINE]; struct args args; struct result result; while(fgets(sendline, MAXLINE, fp) != NULL) { if (sscanf(sendline, "%ld%ld", &args.arg1, &args.arg2) != 2) { printf("invalid input : %s", sendline); continue; } printf("CLIENT : arg1 = %ld\t arg2 = %ld\n", args.arg1, args.arg2); args.arg1 = htonl(args.arg1); args.arg2 = htonl(args.arg2); writen(sockfd, &args, sizeof(args)); if (readn(sockfd, &result, sizeof(result)) == 0) printf("str_cli : server terminated prematurely\n"); printf("CLIENT : %ld\n", ntohl(result.sum)); } }
구조체는 아래와 같습니다.
struct args { unsigned long arg1; unsigned long arg2; }; struct result { unsigned long sum; };
실행하면 아래와 같이 나옵니다.
Quote:
[root@tacstar Stevens]# ./tcpcli02 192.168.1.46
11 22 <--- 입력
CLIENT : arg1 = 11 arg2 = 22
SERVER : arg1 = 11 arg2 = 0 <--- 왜 0이 나올까요?
CLIENT : CLIENT : 184549376 <--- 이건 또 왜그렇죠? ntohl();을 썼는데...
Forums:
1. SERVER 측에서 ntohl(args.arg2) 가 0으로 찍히는
1. SERVER 측에서 ntohl(args.arg2) 가 0으로 찍히는 것은 분명 이상하군요. 코드 상으로는 문제 없어보입니다. 서버와 클라이언트의 struct args 구조가 틀리거나 readline(), writen() 등의 구현이 잘못되어있지 않나 추측됩니다.
2. SERVER 측에서 result.sum을 계산하는 코드에 오류가 있습니다. 다음과 같이 수정되어야 합니다.
result.sum = htonl(ntohl(args.arg1) + ntonl(args.arg2));
n = readline (...) 의 n을 출력 해보세요.writ
n = readline (...) 의 n을 출력 해보세요.
writen(...) 라인의 쓴 바이트도 출력 해보시고요.
readline에서 받은 값들을 hex 로 바이트 단위로 찍어보시고
writen 함수내에서도 바이트 단위로 찍어 보세요.
screen + vim + ctags 좋아요~
음... 해결은 했는데...
감사합니다. *^^*
문제는 readline(); 함수더군요.
그런데 더 웃낀 문제가 있습니다.
클라이언트 코드
서버코드
실행화면
마지막 클라리언트의 출력(두수의 합)하는 것을 보면 이상하게 나오네요.
분명 클라이언측에서 출력 시, ntohl(); 함수를 사용했는데...
ntohl();을 빼고 하면 정상적인 값이 나옵니다.
당신들을 사랑합니다.
result.sum = htonl(args.arg1) + htonl(ar
result.sum = htonl(args.arg1) + htonl(args.arg2);
이코드가 이상한데요. 왜 network byte ordering 한걸 더하나요?
어떨땐 코드 째려보기 신공이 디버깅이 빠를때가 있으니 이용해 보세요.
screen + vim + ctags 좋아요~
음...
서버측 코드를 보시면 printf문에서 args구조체 값을 출력하는데
ntohl(); 함수를 사용하셨네요. *^^*
printf(); 함수의 인자로 넘겨준 값은 변하는게 아니겠죠.
즉, 코드상에선 args 구조체 값은 여전히 network byte order로
되어 있군요. 그 값에 다시 htonl(); 함수를 사용하니 이상하게
나오는거 아닌가요?
많이 헷갈리는 부분인거 같네요. 그래서 값을 읽은 후에는 바로 그 값을
host byte order 로 바꿔준 후에 사용하는게 좋을꺼 같네요. 그럼...
H/W가 컴퓨터의 심장이라면 S/W는 컴퓨터의 영혼이다!
댓글 달기