[Socket프로그래밍] toupper() 함수가 동작을 안하는 이유
글쓴이: gyxor / 작성시간: 일, 2006/11/05 - 12:53오전
1 #include<unistd.h> 2 #include<stdio.h> 3 #include<ctype.h> 4 #include<sys/types.h> 5 #include<sys/socket.h> 6 #include<netinet/in.h> 7 8 #define SIZE sizeof(struct sockaddr_in) 9 10 int newsocket; 11 12 main() 13 { 14 int c; 15 int sockfd; 16 int newsockfd; 17 struct sockaddr_in server = {AF_INET, 9001 , INADDR_ANY}; 18 19 sockfd = socket(AF_INET, SOCK_STREAM, 0); 20 bind(sockfd, (struct sockaddr *) &server, SIZE ); 21 listen(sockfd, 5); 22 while(1) 23 { 24 if( (newsockfd = accept(sockfd, NULL, NULL)) == -1) 25 { 26 perror("accept call failed"); 27 continue; 28 } 29 if( fork() == 0) 30 { 31 while(1) 32 { 33 recv(newsockfd, &c, 1, 0); 34 c = toupper(c); 35 send(newsockfd, &c, 1, 0); 36 37 } 38 } 39 } 40 return 0; 41 }
위는 Server 소스입니다.
1 #include<ctype.h> 2 #include<sys/types.h> 3 #include<sys/socket.h> 4 #include<netinet/in.h> 5 6 #define SIZE sizeof(struct sockaddr_in) 7 8 main() 9 { 10 char c,rc; 11 int size; 12 int sockfd; 13 struct sockaddr_in server = {AF_INET, 9001}; 14 server.sin_addr.s_addr = inet_addr("x.x.x.x"); 15 16 sockfd = socket(AF_INET, SOCK_STREAM, 0); 17 connect(sockfd, (struct sockaddr *)&server, SIZE); 18 while(1) 19 { 20 c = getchar(); 21 send(sockfd, &c, 1, 0); 22 recv(sockfd, &rc, 1, 0); 23 printf("%c", rc); 24 } 25 } 26
위는 Client 소스입니다.
Client에서 Server로 char를 보내면 server에서는 이를 toupper함수를 돌린후 결과를 다시 Client로 보내주는 프로그램입니다.
실제로 에러없이 컴파일되는 소스입니다.
위 소스를 돌려보면 한가지 이상한점이 client에서 입력을 한 문자들이
소문자에서 대문자로 바뀌지 않은것을 볼 수 있습니다.
하지만 Server Source 14번째 줄에서 char c; 로 된것을
char c = 0;
으로 바꾸어주면 소문자-> 대문자 로 정상적으로 실행이 되는것을 볼 수 있습니다.
c라는 변수를 초기화 한것과 초기화 하지 않은 것이 왜 toupper함수를 동작하게 만드는 조건이 되는것인지 도무지 알 수가 없습니다.
소스를 돌려보기 귀찮으시겠지만
client의 14번째 줄에
server.sin_addr.s_addr = inet_addr("x.x.x.x");
아이피 부분만 채워넣으셔서 ..
한번 테스트 해보시면 정말 이상하다는것을 알게 되실 것입니다.
답변 부탁드립니다.
Forums:
추가..
참고로 gcc 4.0에서 테스트 했을때는 저런 현상이 나타나지 않았습니다.
하지만 구버젼 gcc 3.2.3 에서는 저련 현상이 발생을 합니다. 버그로 봐야 하는것인가요?
server에서 c를 찍어보면 아실겁니다
printf()에서 %c로 찍지말고 integer 값 전체를 찍어보세요.
서버 쪽 소스에서
서버 쪽 소스에서 이게 좀 마음에 걸리네요.
14 int c;
33 recv(newsockfd, &c, 1, 0);
34 c = toupper(c);
35 send(newsockfd, &c, 1, 0);
int형의 크기는 1바이트가 아닌데 이러면 그중의 맨 앞에 있는 1바이트만 읽고 쓰게 되죠.
네트워크 프로그램 짤때....
주고받는 데이터의 형식이나 크기에 아주 민감하기 때문에 지금 char를 주고 받는다면 최소한 casting은 필요 할 것을 생각됩니다. 위분이 이야기 한것 처럼 보내기 전에 형을 변경해서 시도 보고 결과를 일러 주시면,
저는 왜 못하냐면, 검증할 컴파일러도 없고, 에또 중국 출장이고 에또 귀찮기도 하고 새 주실분~
죄송합니다.
int main(int argc, char* argv[], char* arge[])
{
return 0;
}
int main(int argc, char* argv[], char* arge[])
{
return 0;
}
감사합니다.
int 형으로 선언한것이 문제였군요;
초기화를 한 경우엔 정상수행이 된 것이 좀 이상하지만
casting을 안한것은 사실이므로 프로그래밍 실수로 봐야겠군요;
정말 답변감사드립니다.
댓글 달기