Mail Archives: cygwin/2005/09/17/07:56:43
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/
- Raw text -