Unable to create a UDP client from thread?


 
Thread Tools Search this Thread
Top Forums Programming Unable to create a UDP client from thread?
# 1  
Old 12-14-2010
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();
    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 ) {}
}

The following codes work!!! WHY? WHY? I ready have no idea!
Code:
 
int main ( void ) {
 TCP();
 while ( 1 ) {}
}

---------- Post updated at 12:30 PM ---------- Previous update was at 11:40 AM ----------

The problem properly cause by the signal and threading. But I still have no idea.
# 2  
Old 12-14-2010
Have a look at pthread_sigmask.
# 3  
Old 12-19-2010
Hi,

The answer from fpmurphy is short, but up to the point. Let me explain a little bit; In a multi-threaded process, a signal handler process-wide, that is global to all threads. However, when the signal is delivered, the system library / kernel picks up a particular thread that shall run the handler. This might be any thread in the process.

In your particular example, you wish that the handler runs in the context of thread1, so that the recvfrom() gets interrupted. But, unless you force it too, the handler may run in the context of the main thread. In that case, nothing will happen. This is likely what you are experiencing.

The way to force the handler to run in the context of thread1 (or equivalently, we say the signal to be delivered to thread1) is using pthread_sigmask() as mentioned by fpmurphy. Please refer to example in the link provided above, to see how it works. Incidentally, this example was my first contribution to the SUSv3 standard; so if you have questions please feel free to ask Smilie

And finally, I would suggest to resort other strategies than alarm() & co. to implement a timeout on the receive operation if you're multi-threaded.

Cheers, Loïc.
# 4  
Old 12-19-2010
Quote:
Originally Posted by Loic Domaigne
Hi,

The answer from fpmurphy is short, but up to the point. Let me explain a little bit; In a multi-threaded process, a signal handler process-wide, that is global to all threads. However, when the signal is delivered, the system library / kernel picks up a particular thread that shall run the handler. This might be any thread in the process.

In your particular example, you wish that the handler runs in the context of thread1, so that the recvfrom() gets interrupted. But, unless you force it too, the handler may run in the context of the main thread. In that case, nothing will happen. This is likely what you are experiencing.

The way to force the handler to run in the context of thread1 (or equivalently, we say the signal to be delivered to thread1) is using pthread_sigmask() as mentioned by fpmurphy. Please refer to example in the link provided above, to see how it works. Incidentally, this example was my first contribution to the SUSv3 standard; so if you have questions please feel free to ask Smilie

And finally, I would suggest to resort other strategies than alarm() & co. to implement a timeout on the receive operation if you're multi-threaded.

Cheers, Loïc.
Thanks, I will try it today.
Login or Register to Ask a Question

Previous Thread | Next Thread

9 More Discussions You Might Find Interesting

1. Forum Support Area for Unregistered Users & Account Problems

Unable to create new thread

Hi. I registered, but when trying to post, I get ... "Sorry, you do not have enough Bits to post a new thread" Google & Forum search showed some hits, but no solution. Please advide. Thanks! (1 Reply)
Discussion started by: gehe
1 Replies

2. Forum Support Area for Unregistered Users & Account Problems

Unable to post or reply thread after login

I am unable to post reply to a thread. Whenever I will reply to any post I get the message every time : The message you have entered is too short. Please lengthen your message to at least 5 characters. Even though length of the message is more than required. for example I tried to post ... (3 Replies)
Discussion started by: Unregistered
3 Replies

3. IP Networking

How to create a multi-chat server using UDP?

Hifriends I have a doubt . how to create a multi-chat server using UDP which can run on MAC systems.. Thank u in advance (3 Replies)
Discussion started by: babbu25
3 Replies

4. Programming

UDP linux client and Windows server

Hi, I have a situation where i need to communicate a linux client with a windows server, I am using a UDP socket communication channel. I am able to send packets from my linux clients to the windows server but unable to receive any data packet from the server. Do i need to make any setting in... (0 Replies)
Discussion started by: John20
0 Replies

5. Forum Support Area for Unregistered Users & Account Problems

unable to post thread

Hello, I'd like to post a aix thread but I'm unable to. Please let me know why this is happening. Thanks.... (1 Reply)
Discussion started by: sullivjp
1 Replies

6. UNIX for Advanced & Expert Users

HOW to create UDP Concurrent Server

HI I want to create a UDP concurrent server can any one give the code for UDP concurrent server (8 Replies)
Discussion started by: chanikya
8 Replies

7. Programming

UDP socket - can both client and server recv and send

Hi, Am very new to socket programming. When we use UDP sockets to communicate between two processess, will both the client/server socket be able to send/recv ? meaning can sendto()/ recvfrom() be used on both server and client? It could be useful even if anybody provide some link on socket... (1 Reply)
Discussion started by: rvan
1 Replies

8. IP Networking

i want a UDP Client receiving program

Hi I want a UDP client receiving program. Here is the scenario. The client has to listen to the UDP server and has to acknowledge back on receiving data from the server. Can anyone help me out. regards, Nirmala (1 Reply)
Discussion started by: Nirmala
1 Replies

9. Post Here to Contact Site Administrators and Moderators

Unable to open thread

I am unable to open the mimesender thread. I get the following message when clicking on https://www.unix.com/showthread.php?p=33233#post33233 : (2 Replies)
Discussion started by: dangral
2 Replies
Login or Register to Ask a Question