리눅스서버와 윈도우즈클라이언트간에 통신

jjjjrr의 이미지

안녕하세요
리눅스서버와 윈도우즈클라이언트간에
통신을 하려구합니다
리눅스서버에서는
클라이언트로부터접속을 받고
쓰레드로 작업을 합니다
아래코드가 쓰레드내의 작업입니다
근데 이상하게동작합니다
윈도우즈클라이언트로부터 접속은되구여
메세지도 받읍니다
근데 서버에서는 클라이언트에게
메세지를 주어야되는데 주지를 못하는것같읍니다
윈도우즈클라이언트에서는 메세지를 받는부분에서
블락되어버립니다
그러니까 메세지를 받으려구 기다리고있는데
서버에서 주지를 않으니까
계속 기다리는모양입니다
평생토록 기다릴 태세입니다
아래코드한번 살펴봐주십시요
그리구여
윈도우즈 클라이언트를 강제종료시켜버리면
리눅스서버도
파이프가 끊어졌읍니다 하는메세지를 내고는
프로그램이 종료되어버립니다
이러면 안되는데
그 클라이언트의 작업을 하는 소켓과 쓰레드만제거되구
서버는 계속 다른클라이언트의 연결을 기다리고있어야되는데
왜 프로그램이 종료될까요
조언부탁드립니다
printf("dnsaddr=%s peeraddr=%s \n",dnsaddr,peeraddr);
여기까지는 출력이됩니다

    while(1)
    {
 
        if (read(sockfd, buf, 255) <= 0)  
        {
            write(sockfd, "bye bye\n", 8);
            close(sockfd);
            pthread_exit((void *)NULL);
 
        }
 
        sprintf(query, "./bindset %s %d", buf,clientinfo.addr);
        sprintf(peeraddr, "%d",clientinfo.addr);
        FILE *fp;
        int state;
   printf("query=%s     \n",query);  
        int i;
        for( i = 0; i < 2 ; i++)
        {
             fp = popen(query, "r");
             if (fp == NULL)
             {
                perror("erro : ");
                write(sockfd, "query_failed\n", 255);
                close(sockfd);        
                pthread_exit((void *)NULL);
     
             }
             state = pclose(fp);

             char *ptr, **pptr;
             char str[INET6_ADDRSTRLEN];
             struct hostent *hptr;
             
             hptr = gethostbyname(buf);
   printf("hptr->h_addrtype=%d     \n",hptr->h_addrtype);  

        switch(hptr->h_addrtype)
             {
                  case AF_INET:
#ifdef  AF_INET6
                  case AF_INET6:
#endif
                         pptr = hptr->h_addr_list;
                         for( ; *pptr != NULL; pptr++)
                         {  
                              sprintf(dnsaddr,"%s",inet_ntop(hptr->h_addrtype,*pptr,str,sizeof(str)));
       printf("dnsaddr=%s peeraddr=%s    \n",dnsaddr,peeraddr);  
                                  if(strcmp(peeraddr,dnsaddr) == 0)
                                  {
                                       write(sockfd, "query_ok\n", 255);
                                       close(sockfd); 
                                       pthread_exit((void *)NULL);  
       
                                   }
                           }
                         break;
                  default:
                         break;
               
              } 

 
        
          }

        
        memset(buf, 0x00, 255); 
     }

      printf("AF_INET=%d     \n",AF_INET);  
      write(sockfd, "query_failed", 255); 
      close(sockfd);  
      pthread_exit((void *)NULL); 
      return;
[/code]
zedai1972의 이미지

좀 의심나는 부분이 두군데 있네요.

1.

                 if(strcmp(peeraddr,dnsaddr) == 0)
    

에서 peeraddr, dnsaddr 이 같지 않으면,
클라이언트에게 write를 않하구 무한루프를..
peeraddr은 int형인가?, dnsaddr은 string이구..
printf로 출력은 되겠지만, strcmp로 비교시 올바른 비교가
안될거 같은데요..
2.

                write(sockfd,"~",255);
    

위처럼 코딩하면 sockfd로 문자열외에 소켓버퍼의 255바이트
가 다 가지 않나요? 가긴 가겠지만...

역시 확실한 방법은 gdb로 디버깅을 하면 한번에 알 수 있을텐데..
그럼 수거여~

\\(^^ )^^)// **

jjjjrr의 이미지

안녕하세요
답변감사합니다
화일문을 제거하니 됩니다
근데제가 이해가 안되서 다시질문입니다
화일문안의 이부분

 if (read(sockfd, buf, 255) <= 0) 
        {
            write(sockfd, "bye bye\n", 8);
            close(sockfd);
            pthread_exit((void *)NULL);

        } 

소켓으로부터 읽을때 다읽으면
이프문 안의 코드가 실행되는것아닌가요
그래서 화일루프를 빠져나간다고 생각했는데
그게아닌가여
리드로 소켓버퍼을 읽구여
그다음은 어떻게되나요
위코드의 이프문안의 코드는
언제실행되나요[/code]
zedai1972의 이미지

제가 제대로 알고 잇는지 모르겠지만 .. 상대측이 close를 하면 받는 측 read 가 eof(0)를 리턴하는 걸로 알고 잇는데요.

저같으면 read의 리턴값으로 -1 하고 0 을 구분해서 처리할거 같아요.

\\(^^ )^^)// **

kslee80의 이미지

recv() 의 리턴값은 실제로 받은 데이타의 길이를 의미합니다.
그렇기에, recv() 콜의 세번째 인자값보다 클수 없으며,
-1 의 경우는 모든 시스템 콜이 그러하듯 에러상황을 의미합니다.
0의 경우는 윗분이 쓰신대로, 연결이 끊어진 경우를 의미합니다.

socket() 콜로 얻어지는 fd 자체가 open() 콜에서 리턴되는 fd 와
별 차이가 없기 때문에, (실제 코딩시의 관점입니다)
recv() 대신 read() 를 쓸수 있으며,
결과적으로, recv() 의 리턴값은 파일에 대해 read() 를 호출했을시에
리턴값과 의미하는 바가 비슷합니다.

cjy1126의 이미지

소켓으로부터 읽을때 다읽으면 
이프문 안의 코드가 실행되는것아닌가요 

read 함수의 return 값은 읽은 data의 size입니다.

즉... 제대로 data를 읽는다면 if문은 실행되지 않습니다.

보통 if문안에는 에러처리를 하죠.

만약 if문이 실행된다면 rst같은 에러를 받아서 -값이 나왔거나, 정상적인 종료로 fin을 받아서 0값이 넘어왔을때입니다.

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.