Unable to create a UDP client from thread?

This is a discussion on Unable to create a UDP client from thread? within the C Programming forums, part of the General Programming Boards category; I try to initial a UDP client from threading, but it doesn't work? why? These codes from the textbook Code: ...

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

    Unable to create a UDP client from thread?

    I try to initial a UDP client from threading, but it doesn't work? why?


    These codes from the textbook
    Code:
    #define ECHOMAX         255     /* Longest string to echo */
    #define TIMEOUT_SECS    2       /* Seconds between retransmits */
    #define MAXTRIES        5       /* Tries before giving up */
    int tries=0;   /* Count of times sent - GLOBAL for signal-handler access */
    void CatchAlarm(int ignored)     /* Handler for SIGALRM */
    {
        tries += 1;
    }
    static void DieWithError(char *errorMessage)
    {
        perror(errorMessage);
        exit(1);
    }
    void TCP () {
        int sock;                        /* Socket descriptor */
        struct sockaddr_in echoServAddr; /* Echo server address */
        struct sockaddr_in fromAddr;     /* Source address of echo */
        unsigned short echoServPort;     /* Echo server port */
        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;                /* String to send to echo server */
        char echoBuffer[ECHOMAX+1];      /* Buffer for echo string */
        int echoStringLen;               /* Length of string to echo */
        int respStringLen;               /* Size of received datagram */
    
    //The IP is invalid since I need to test the function about timeout!!
        servIP = "192.168.1.254";           /* First arg:  server IP address (dotted quad) */
        echoString = "abc";       /* Second arg: string to echo */
    
        if ((echoStringLen = strlen(echoString)) > ECHOMAX)
            DieWithError("Echo word too long");
    
            echoServPort = atoi("12345");  /* Use given port, if any */
    
        /* Create a best-effort datagram socket using UDP */
        if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)
            DieWithError("socket() failed");
    
        /* 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(echoServPort);       /* Server port */
    
        /* Send the string to the server */
        if (sendto(sock, echoString, echoStringLen, 0, (struct sockaddr *)
                   &echoServAddr, sizeof(echoServAddr)) != echoStringLen)
            DieWithError("sendto() sent a different number of bytes than expected");
    
        /* Get a response */
        fromSize = sizeof(fromAddr);
        alarm(TIMEOUT_SECS);        /* Set the timeout */
      When I call this function from a thread, it is blocking here, and no response anymore!
        while ((respStringLen = recvfrom(sock, echoBuffer, ECHOMAX, 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, echoStringLen, 0, (struct sockaddr *)
                                &echoServAddr, sizeof(echoServAddr)) != echoStringLen)
                        DieWithError("sendto() failed");
                    alarm(TIMEOUT_SECS);
                }
                else
                    DieWithError("No Response");
            }
            else
                DieWithError("recvfrom() failed");
        }
    
        /* recvfrom() got something --  cancel the timeout */
        alarm(0);
    
        /* null-terminate the received data */
        echoBuffer[respStringLen] = '\0';
        printf("Received: %s\n", echoBuffer);    /* Print the received data */
    
        close(sock);
        exit(0);
    }

    These code does not work!
    Code:
    static void* testRun () {
        TCP();
        return NULL;
    }
    int main ( void ) {
        pthread_t tid;
        pthread_attr_t tx;
        pthread_attr_setdetachstate( &tx, PTHREAD_CREATE_DETACHED );
        pthread_attr_init( &tx );
        if ( pthread_create( &tid, &tx, testRun, NULL ) )
            exit( -1 );
      while ( 1 ) {}
      return 0;
    }

    The following codes work!!! WHY? WHY? I ready have no idea!
    Code:
     
    int main ( void ) {
     TCP();
     while ( 1 ) {}
    }
    Last edited by sehang; 12-13-2010 at 10:59 AM. Reason: The source code has mistaks.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,669
    Returning from main() kills your process, including any threads.

    You can join with the thread (and not create it detached). Or call pthread_exit() at the end of main().

    gg

  3. #3
    Registered User
    Join Date
    Dec 2010
    Posts
    13
    Quote Originally Posted by Codeplug View Post
    Returning from main() kills your process, including any threads.

    You can join with the thread (and not create it detached). Or call pthread_exit() at the end of main().

    gg
    Sorry, I forgot put the code of forever loop at the main function, it should be here; and I will try to modify the thread by using join.

  4. #4
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,669
    You should initialize "tx" before using it.

    "testRun" has an incorrect signature.

    gg

  5. #5
    Registered User
    Join Date
    Dec 2010
    Posts
    13
    Quote Originally Posted by Codeplug View Post
    You should initialize "tx" before using it.

    "testRun" has an incorrect signature.

    gg
    What does incorrect signature means? Thanks.

  6. #6
    Registered User
    Join Date
    Dec 2010
    Posts
    13
    It still does not work! The following codes are modified, but no effect!
    Code:
    static void* testRun () {
        TCP();
        pthread_exit(NULL);
        return NULL;
    }
    
    
    int main ( void ) {
        pthread_t thread1;
        assert( pthread_create( &thread1, NULL, &testRun, NULL) == 0 );
        assert( pthread_join( thread1, NULL) == 0 );
        while ( 1 ) {}
        return 0;
    }

  7. #7
    Registered User
    Join Date
    Dec 2010
    Posts
    13
    It properly about the function sigaction() with threading, is does not work, why signal and threading is conflict here?

  8. #8
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,669
    >> What does incorrect signature means?
    A thread function returns a void* and takes a single void*.
    http://pubs.opengroup.org/onlinepubs...ad_create.html

    >> ... sigaction() with threading, ...
    Read this and the example code: http://pubs.opengroup.org/onlinepubs...d_sigmask.html
    Additional information: http://pubs.opengroup.org/onlinepubs...html#tag_15_04

    gg

  9. #9
    Registered User
    Join Date
    Dec 2010
    Posts
    13
    Hi, I still have no idea what does 'A thread function returns a void* and takes a single void*.'.

    1.
    Is it means, I should use
    Code:
    pthread_create( &thread1, NULL, &testRun, NULL) == 0
    instead of
    Code:
    pthread_create( &thread1, NULL, testRun, NULL) == 0
    or

    Using
    Code:
    void* testRun () {
         ...
        return (void*)NULL;
    }
    2. Where should I put the signalwait function, as the example you gave, every thread should has own signalwait function, put when I using UDP and call recvfrom(...), is the signalwait function should be placed before the recvfrom(...) function? That is,

    Code:
        int       sig_caught;    /* signal caught       */
        int       rc;            /* returned code       */
    
    
        rc = sigwait (&signal_mask, &sig_caught);
        if (rc != 0) {
            /* handle error */
        }
        switch (sig_caught)
        {
        case SIGINT:     /* process SIGINT  */
            ...
            break;
        case SIGTERM:    /* process SIGTERM */
            ...
            break;
        default:         /* should normally not happen */
            fprintf (stderr, "\nUnexpected signal %d\n", sig_caught);
            break;
        }
    
        while ((respStringLen = recvfrom(sock, echoBuffer, ECHOMAX, 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, echoStringLen, 0, (struct sockaddr *)
                                &echoServAddr, sizeof(echoServAddr)) != echoStringLen)
                        DieWithError("sendto() failed");
                    alarm(TIMEOUT_SECS);
                }
                else
                    DieWithError("No Response");
            }
            else
                DieWithError("recvfrom() failed");
        }
    ...

  10. #10
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,669
    >> A thread function returns a void* and takes a single void*.
    "void* testRun(void*)"

    Just forget about using signals at all. Learn how to use use select() instead.
    http://beej.us/guide/bgnet/

    gg

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Not able to create 1024 socket request.
    By rahul.shukla in forum Networking/Device Communication
    Replies: 3
    Last Post: 02-15-2010, 02:49 PM
  2. Error in creating socket in a client (UDP)
    By ferenczi in forum Networking/Device Communication
    Replies: 2
    Last Post: 11-27-2008, 10:11 AM
  3. Chat udp server/client
    By Phoenix_Rebirth in forum C Programming
    Replies: 1
    Last Post: 11-17-2008, 11:30 AM
  4. Using select() for client UDP
    By jazzman83 in forum C Programming
    Replies: 2
    Last Post: 04-03-2007, 05:31 AM
  5. unable to link NCB programs
    By rohit in forum Windows Programming
    Replies: 0
    Last Post: 05-12-2002, 09:47 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21