This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: socket troubles


Hi,

thanks for the advices, and sorry for the VC++ project

So, I added sigchld() event and replaced shutdown() by close()


It works cool....


But now I try to change server code to use select() for my children
and I have the same behaviour
(anyway, it takes more "client queries" to hang...)

sometimes alos, if there's no hang, children refuse to die even if I
close the client processes !?



server code
-----------


#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>
#include <setjmp.h>
#ifdef SUN
  #include <signal.h>
#else
  #include <sys/signal.h>
#endif
#include <sys/wait.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#define SA    struct sockaddr
#define SA_IN struct sockaddr_in

#include <sys/time.h>
#include <fcntl.h>

#ifndef INADDR_NONE
#define INADDR_NONE ((unsigned long) -1)
#endif 


/*
*/
void loop(int sock)
{
  int r, ret=0;
  struct timeval tv;
  fd_set readfds, exceptfd;
  char tmp[500];

  while(1)  
  {
    FD_ZERO(&readfds);
    FD_SET(sock, &readfds);
    FD_ZERO(&exceptfd);
    FD_SET(sock, &exceptfd); 
    tv.tv_sec=10;
    tv.tv_usec=0;

    r = select(FD_SETSIZE, &readfds, NULL, &exceptfd, &tv);
    
    switch (r)
    {
      /* time-out */
      case 0 :
        printf("+");
      break;
        
      /* trouble */
      case -1 :
      {
        if (errno==EINTR)
        {
          puts("client interrup...");
        }
        else if (errno==ECHILD)
        {
          puts("no child anymore");
        }
        else
        {
          printf("select exit with -1 : errno = %d\n", errno);
          perror("");
        }  
        
        goto fin;
      }
      break;
   
      
      /* */
      default :
      {
        if ( FD_ISSET(sock, &readfds) )
        {
          if ( FD_ISSET(sock, &exceptfd) )
          {
            printf("<<<<");
            goto fin;
          }
          
          ret = recv(sock, tmp, 100, 0);
          
          //if (ret<=0)
            goto fin;
          
        }
        else
        {
          printf("FD_ISSET errno : %d\n", errno);
          goto fin;
        }
      }
      break;  
    }
  
  }  
  

fin:
  FD_CLR(sock, &readfds);
  FD_CLR(sock, &exceptfd);  
}







/*
*
*/
static void sigchld(int n)
{
  int pid;

  while(1)
  {
    pid = wait3(NULL, WNOHANG,NULL);
    
    if (pid>0) 
      printf("child %d stops with signal %d\n", pid, n);
    else
      break;  
  }
  
  // ???
  signal(SIGCHLD,sigchld);
}






/*
*/
static int init_nw(char *address, int port, SA_IN *servaddr)
{
  struct hostent *inf;
  int f_on=1;
  int s;
  
  s = socket(AF_INET, SOCK_STREAM, 0);

  if (s<0)       
    return 0;

  setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (void *) &f_on, sizeof(int));
  setsockopt(s, SOL_SOCKET, SO_KEEPALIVE, (void *) &f_on, sizeof(int));

  memset(servaddr, 0, sizeof(SA_IN));
  servaddr->sin_family = AF_INET;
  servaddr->sin_port = htons((unsigned short)port);

  if (address==NULL || strlen(address)==0)
    servaddr->sin_addr.s_addr = htonl(INADDR_ANY);
  else
    servaddr->sin_addr.s_addr = inet_addr(address); 

  if (servaddr->sin_addr.s_addr==INADDR_NONE)
  {
    inf = gethostbyname(address);

    if (inf==NULL)
      return 0;

    memcpy( &servaddr->sin_addr.s_addr, inf->h_addr, inf->h_length );
  }

  return s;
}






/*
*
*/
int main(int argc, char *argv[]) 
{
  int sock, sd, r;
  SA_IN servaddr;
  int rf, f=0;
  char ok[2048];
  SA addr;
  socklen_t fromlen;
  struct timeval tv;
  fd_set readfs; 
  
  
  sd = init_nw("", 5600, &servaddr);

  if (sd<0)
    exit(500);

  // blocking
  r = fcntl(sd, F_SETFL, f & (~O_NONBLOCK) );
 
  if (r<0)
    exit(500);

  if ( bind(sd, (SA *) &servaddr, sizeof(servaddr))==-1 )
    exit(501);

  signal(SIGCHLD,sigchld);

  r = listen( sd, 5);

  
  while(1)
  {
    errno=0;

    FD_ZERO(&readfs);       /* clears out, so that it doesn't contain
any file descriptors. */
    FD_SET(sd, &readfs);
    
    tv.tv_sec = 5;
		tv.tv_usec = 0;

    r = select(FD_SETSIZE, &readfs, NULL, NULL, &tv);
    
    switch(r)
    {
      case 0 :
      {
        printf(".");
      }
      break;
      
      
      case -1 :
      {
        if (errno==EINTR)
        {
          puts("bye pass interrup...");
        }
        else if (errno==ECHILD)
        {
          puts("no child anymore");
        }
        else
        {
          printf("select exit with -1 : errno = %d\n", errno);
          perror("");
          goto fin;
        }  
      }
      break;

      
      //---
      //
      default :
      {
        if ( FD_ISSET( sd, &readfs) )
        {
          fromlen = sizeof(SA);
          sock = accept(sd, (SA *) &addr, &fromlen);
          
          if (errno==0)
          {
            rf = fork();
      
            if (!rf)
            {
              fcntl(sock, F_SETFL, f & (~O_NONBLOCK) );
              close(sd);
      
              recv(sock, ok, 2048, 0);
                
              sprintf(ok, "01101996 123 444");
              send(sock, ok, strlen(ok)+1, 0);
                
              loop(sock);
              
              close(sock);
              goto fin;
            }
            
            close(sock);
          }
          else
          {
            perror(">>>");
          }
        }
        else
        {
          printf("FD_ISSET errno : %d\n", errno);
          goto fin;
        }  
      }  
    }  
  }


fin:
  FD_CLR(sd, &readfds);
  close(sd);
  
  return 0;
}

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]