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
UDPServer.c:100: error: expected âwhileâ before â}â token
I really am at a loss with all of this. Any help will be greatly appreciated.
UDPServer.c
Code:
#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
Code:
#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
Code:
#include <stdio.h>
#include <stdlib.h>
void DieWithError(char *errorMessage)
{
perror(errorMessage);
exit(1);
}