Thread: How to use sigmask in order to make signals can be processed by a thread

  1. #1
    Registered User
    Join Date
    Dec 2010
    Posts
    13

    How to use sigmask in order to make signals can be processed by a thread

    Hi,

    I have a UDP server and client program, and they must run within a program, so I decided two threads, one for UDP server and another for UDP client.

    The simple architecture is shown in attachment.

    However, I can't send the packets out on the UDP client, no any time message and sigaction is triggered. Is any sigmask needs? If it is, then where should I put the mask?

    The following are the source codes

    The UDP server
    Code:
    static void SIGIOHandler( int signalType ) {
        struct sockaddr_in clntAddr;
        unsigned int clntLen;
        int recvMsgSize;
        UINT8 buf[ MSG_SIZE ];
        do {
            clntLen = sizeof( clntAddr );
            if ( ( recvMsgSize = recvfrom( srvSock, buf, MSG_SIZE, 0, ( struct sockaddr* )&clntAddr,&clntLen ) ) < 0 ) {
                if ( errno != EWOULDBLOCK ) {
                          ...Error handler
                }
            } else {
                printf( "Handling client %s\n", inet_ntoa( clntAddr.sin_addr ) );
                if ( Sendto( srvSock, buf, recvMsgSize, 0, ( struct sockaddr* )&clntAddr, sizeof( clntAddr ),
                __FILE__, __LINE__ ) != recvMsgSize ) {
                   ...Error handler
                }
            }
        }  while ( recvMsgSize >= 0 );
        printf( "%s completed\n", inet_ntoa( clntAddr.sin_addr ) );
    }
    
    
    void Server_Constructor () {
        char buf[ 128 ];
        struct sockaddr_in echoServAddr;
        struct sigaction handler;
    
        /* Initiating socket. */
        srvSock = socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP );
        memset( &echoServAddr, 0, sizeof( echoServAddr ) );
        echoServAddr.sin_family = AF_INET;
        echoServAddr.sin_addr.s_addr = htonl( INADDR_ANY );
        echoServAddr.sin_port = htons( ( unsigned short )23456 );
        Bind( srvSock, ( struct sockaddr* )&echoServAddr, sizeof( echoServAddr ) );
    
        /* Initiating signal handler. */
        handler.sa_handler = SIGIOHandler;
        if ( sigfillset( &handler.sa_mask ) < 0 ) {
          ...Error handler
        }
        handler.sa_flags = 0;   /* No flags */
        if ( sigaction( SIGIO, &handler, 0 ) < 0 ) {
          ...Error handler
        }
        if ( fcntl( srvSock, F_SETOWN, getpid() ) < 0 ) {
          ...Error handler
        }
        if ( fcntl ( srvSock, F_SETFL, O_NONBLOCK | FASYNC ) < 0 ) {
          ...Error handler
        }
    
        /* Wait forever. */
       ....
    }
    The UDP client
    Code:
    static void CatchAlarm ( int ignored ) {
        tries += 1;
    }
    
    void Client_Sendto ( const struct sockaddr* dest_addr, const void* message ) {
        int sock;                        /* Socket descriptor */
        struct sockaddr_in echoServAddr; /* Echo server address */
        struct sockaddr_in fromAddr;     /* Source address of echo */
        unsigned int fromSize;           /* In-out of address size for recvfrom() */
        struct sigaction myAction;       /* For setting signal handler */
        char *servIP;                    /* IP address of server */
        char echoString[ MSG_SIZE ] = "123";                /* String to send to echo server */
        char recvbuf[ MSG_SIZE ];
        int respStringLen;               /* Size of received datagram */
    
        servIP = "127.0.0.1";           /* First arg:  server IP address (dotted quad) */
    
        sock = Socket( PF_INET, SOCK_DGRAM, IPPROTO_UDP, __FILE__, __LINE__ );
    
        /* Set signal handler for alarm signal */
        myAction.sa_handler = CatchAlarm;
        if (sigfillset(&myAction.sa_mask) < 0) /* block everything in handler */
            DieWithError("sigfillset() failed");
        myAction.sa_flags = 0;
    
        if (sigaction(SIGALRM, &myAction, 0) < 0)
            DieWithError("sigaction() failed for SIGALRM");
    
        /* Construct the server address structure */
        memset(&echoServAddr, 0, sizeof(echoServAddr));    /* Zero out structure */
        echoServAddr.sin_family = AF_INET;
        echoServAddr.sin_addr.s_addr = inet_addr(servIP);  /* Server IP address */
        echoServAddr.sin_port = htons( ( unsigned short )UDP_PORT );       /* Server port */
    
    The UDP client unable send packet out, I think it can't receive the signal in the thread, so how to do that?
    
        /* Send the string to the server */
        if (sendto(sock, echoString, MSG_SIZE, 0, (struct sockaddr *)
                   &echoServAddr, sizeof(echoServAddr)) != MSG_SIZE)
            DieWithError("sendto() sent a different number of bytes than expected");
    
        /* Get a response */
        fromSize = sizeof( fromAddr );
        alarm( TIMEOUT_SECS );  /* Set the timeout */
        while ((respStringLen = recvfrom(sock, recvbuf, MSG_SIZE, 0,
               (struct sockaddr *) &fromAddr, &fromSize)) < 0)
            if (errno == EINTR)     /* Alarm went off  */
            {
                if (tries < MAXTRIES)      /* incremented by signal handler */
                {
                    printf("timed out, %d more tries...\n", MAXTRIES-tries);
                    if (sendto(sock, echoString, MSG_SIZE, 0, (struct sockaddr *)
                                &echoServAddr, sizeof(echoServAddr)) != MSG_SIZE)
                        DieWithError("sendto() failed");
                    alarm(TIMEOUT_SECS);
                }
                else
                    DieWithError("No Response");
            }
            else
                DieWithError("recvfrom() failed");
        alarm( 0 ); /* Cancel the timeout. */
        Close( sock, __FILE__, __LINE__ );
        printf( "Received: %s\n", recvbuf );    /* Print the received data */
    }
    
    
    static void* SENDER ( void* null ) {
        do {
            Client_Sendto( NULL, NULL );
            sleep( 1 );
        } while ( 1 );
        return NULL;
    }
    
    
    void Client_DebugThread () {
        pthread_t tid;              /* Thread ID. */
        pthread_attr_t rx;          /* Parameter of thread. */
        pthread_attr_init( &rx );   /* Free resources immediately if a thread is terminated. */
        pthread_attr_setdetachstate( &rx, PTHREAD_CREATE_DETACHED );
        pthread_create( &tid, &rx, SENDER, NULL, __FILE__, __LINE__ );
    }

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,971
    http://cboard.cprogramming.com/c-pro...ds-timers.html

    Instead of using signals, use select or poll. Those will tell you when there is something read or write with timeouts.

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. How to make your Thread HOT
    By year2038bug in forum A Brief History of Cprogramming.com
    Replies: 29
    Last Post: 08-30-2005, 06:20 AM
  2. Simple thread object model (my first post)
    By Codeplug in forum Windows Programming
    Replies: 4
    Last Post: 12-12-2004, 11:34 PM
  3. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  4. How to make a thread sleep or std::recv timeout?
    By BrianK in forum Linux Programming
    Replies: 3
    Last Post: 02-26-2003, 10:27 PM
  5. Sign up -- Contest Thread
    By ygfperson in forum A Brief History of Cprogramming.com
    Replies: 70
    Last Post: 05-27-2002, 06:46 PM

Tags for this Thread