[Socket프로그래밍] toupper() 함수가 동작을 안하는 이유

gyxor의 이미지

      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");
아이피 부분만 채워넣으셔서 ..
한번 테스트 해보시면 정말 이상하다는것을 알게 되실 것입니다.
답변 부탁드립니다.

gyxor의 이미지

참고로 gcc 4.0에서 테스트 했을때는 저런 현상이 나타나지 않았습니다.
하지만 구버젼 gcc 3.2.3 에서는 저련 현상이 발생을 합니다. 버그로 봐야 하는것인가요?

채영구의 이미지

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바이트만 읽고 쓰게 되죠.

latex의 이미지

주고받는 데이터의 형식이나 크기에 아주 민감하기 때문에 지금 char를 주고 받는다면 최소한 casting은 필요 할 것을 생각됩니다. 위분이 이야기 한것 처럼 보내기 전에 형을 변경해서 시도 보고 결과를 일러 주시면,
저는 왜 못하냐면, 검증할 컴파일러도 없고, 에또 중국 출장이고 에또 귀찮기도 하고 새 주실분~
죄송합니다.
int main(int argc, char* argv[], char* arge[])
{
return 0;
}

int main(int argc, char* argv[], char* arge[])
{
return 0;
}

gyxor의 이미지

int 형으로 선언한것이 문제였군요;
초기화를 한 경우엔 정상수행이 된 것이 좀 이상하지만
casting을 안한것은 사실이므로 프로그래밍 실수로 봐야겠군요;
정말 답변감사드립니다.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.