Jump to content

Help with C Client/Server Program (UDP Protocal)

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
1 reply to this topic

#1
handsomedan

handsomedan

    Newbie

  • Members
  • Pip
  • 2 posts
I am trying to set this up so that when the client makes a connection with the server, the server will send the current time back to the client, and the client will display it. I'm having a few problems.

*NOTE* I have edited both programs a bit, but I am getting an error message when trying to compile UDPServer. It is as follows ---
UDPServer.c: In function âSIGIOHandlerâ:
UDPServer.c:97: warning: passing argument 2 of âsendtoâ makes pointer from integer without a cast

I really am at a loss with all of this. Any help will be greatly appreciated.

UDPServer.c

#include <stdio.h>      /* for printf() and fprintf() */

#include <sys/socket.h> /* for socket(), bind, and connect() */

#include <arpa/inet.h>  /* for sockaddr_in and inet_ntoa() */

#include <stdlib.h>     /* for atoi() and exit() */

#include <string.h>     /* for memset() */

#include <unistd.h>     /* for close() and getpid() */

#include <fcntl.h>      /* for fcntl() */

#include <sys/file.h>   /* for O_NONBLOCK and FASYNC */

#include <signal.h>     /* for signal() and SIGALRM */

#include <errno.h>      /* for errno */

#include <time.h>       /* for time */


#define ECHOMAX 255     /* Longest string to echo */


void DieWithError(char *errorMessage);  /* Error handling function */

void UseIdleTime();                     /* Function to use idle time */

void SIGIOHandler(int signalType);      /* Function to handle SIGIO */


int sock;                        /* Socket -- GLOBAL for signal handler */


int main(int argc, char *argv[])

{

    struct sockaddr_in echoServAddr; /* Server address */

    unsigned short echoServPort;     /* Server port */

    struct sigaction handler;        /* Signal handling action definition */


    /* Test for correct number of parameters */

    if (argc != 2)

    {

        fprintf(stderr,"Usage:  %s <SERVER PORT>\n", argv[0]);

        exit(1);

    }


    echoServPort = atoi(argv[1]);  /* First arg:  local port */


    /* Create socket for sending/receiving datagrams */

    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0)

        DieWithError("socket() failed");


    /* Set up the server address structure */

    memset(&echoServAddr, 0, sizeof(echoServAddr));   /* Zero out structure */

    echoServAddr.sin_family = AF_INET;                /* Internet family */

    echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */

    echoServAddr.sin_port = htons(echoServPort);      /* Port */


    /* Bind to the local address */

    if (bind(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)

        DieWithError("bind() failed");


    /* Set signal handler for SIGIO */

    handler.sa_handler = SIGIOHandler;

    /* Create mask that mask all signals */

    if (sigfillset(&handler.sa_mask) < 0) 

        DieWithError("sigfillset() failed");

    /* No flags */

    handler.sa_flags = 0;


    if (sigaction(SIGIO, &handler, 0) < 0)

        DieWithError("sigaction() failed for SIGIO");


    /* We must own the socket to receive the SIGIO message */

    if (fcntl(sock, F_SETOWN, getpid()) < 0)

        DieWithError("Unable to set process owner to us");


    /* Arrange for nonblocking I/O and SIGIO delivery */

    if (fcntl(sock, F_SETFL, O_NONBLOCK | FASYNC) < 0)

        DieWithError("Unable to put client sock into non-blocking/async mode");


    /* Go off and do real work; echoing happens in the background */


    for (;;)

        UseIdleTime();


    /* NOTREACHED */

}


void UseIdleTime()

{

    printf(".\n");

    sleep(3);     /* 3 seconds of activity */

}


void SIGIOHandler(int signalType)

{

    time_t currentTime;

    struct sockaddr_in echoClntAddr;  /* Address of datagram source */

    unsigned int clntLen;             /* Address length */


    do  /* As long as there is input... */

    {

        /* Set the size of the in-out parameter */

        clntLen = sizeof(echoClntAddr);


            printf("Handling client %s\n", inet_ntoa(echoClntAddr.sin_addr));


            if (sendto(sock, currentTime, sizeof(currentTime), 0, (struct sockaddr *) 

                  &echoClntAddr, sizeof(echoClntAddr)) != sizeof(currentTime))

                DieWithError("sendto() failed");

    }  while (sizeof(currentTime) >= 0);

    /* Nothing left to receive */

}


UDPClient.c

#include <stdio.h>      /* for printf() and fprintf() */

#include <sys/socket.h> /* for socket(), connect(), sendto(), and recvfrom() */

#include <arpa/inet.h>  /* for sockaddr_in and inet_addr() */

#include <stdlib.h>     /* for atoi() and exit() */

#include <string.h>     /* for memset() */

#include <unistd.h>     /* for close() and alarm() */

#include <errno.h>      /* for errno and EINTR */

#include <signal.h>     /* for sigaction() */


#define BUFFERMAX         255     /* Longest string to receive */

#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 DieWithError(char *errorMessage);   /* Error handling function */

void CatchAlarm(int ignored);            /* Handler for SIGALRM */


int main(int argc, char *argv[])

{

    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 timeBuffer[BUFFERMAX+1];      /* Buffer for echo string */

    int timeStringLen;               /* Length of string to echo */

    int respStringLen;               /* Size of received datagram */


    if ((argc < 2) || (argc > 3))    /* Test for correct number of arguments */

    {

        fprintf(stderr,"Usage: %s <Server IP> [<Echo Port>]\n", argv[0]);

        exit(1);

    }


    servIP = argv[1];           /* First arg:  server IP address (dotted quad) */


    if (argc == 3)

        echoServPort = atoi(argv[2]);  /* Use given port, if any */

    else

        echoServPort = 7;  /* 7 is well-known port for echo service */


    /* 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 */

  

    /* Get a response */

    fromSize = sizeof(fromAddr);

    alarm(TIMEOUT_SECS);        /* Set the timeout */

    while ((respStringLen = recvfrom(sock, timeBuffer, BUFFERMAX, 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);

                alarm(TIMEOUT_SECS);

            } 

            else

                DieWithError("No Response");

        } 

        else

            DieWithError("recvfrom() failed");


    /* recvfrom() got something --  cancel the timeout */

    alarm(0);


    /* null-terminate the received data */

    timeBuffer[respStringLen] = '\0';

    printf("Received: %s\n", timeBuffer);    /* Print the received data */

    

    close(sock);

    exit(0);

}


void CatchAlarm(int ignored)     /* Handler for SIGALRM */

{

    tries += 1;

}


DieWithError.c

#include <stdio.h>

#include <stdlib.h>

void DieWithError(char *errorMessage)

{

perror(errorMessage);

exit(1);

}



#2
dargueta

dargueta

    Writes binary right handed and hex left handed

  • Moderators
  • 4,717 posts
if (sendto(sock, [B][COLOR=Red]&[/COLOR][/B]currentTime, sizeof(currentTime), 0, (struct sockaddr *) 
                  &echoClntAddr, sizeof(echoClntAddr)) != sizeof(currentTime))
                DieWithError("sendto() failed");
This is pretty much guaranteed to segfault on you if you don't have that ampersand there.

Edited by dargueta, 24 March 2010 - 10:04 AM.
Rephrased for clarity

sudo rm -rf /