概述
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <time.h>
#define BUFFER_LENGTH 1024
void ReverseMessage(char buffer[], ssize_t receivedBytesCount);
void ExitWithMessage(const int errorCode, const char * errorMessage)
{
fprintf(stderr, "nnError Msg : %sn", errorMessage);
fprintf(stderr, "Error Code : 0x%Xn", errorCode);
fprintf(stderr, "Location : %s: %dnn", __FILE__, __LINE__);
exit(errorCode);
}
void PrintIPv4(unsigned long ipvalue, FILE * stream)
{
uint8_t a;
uint8_t b;
uint8_t c;
uint8_t d;
a = ipvalue >> 24;
ipvalue -= a * 0x01000000;
b = ipvalue >> 16;
ipvalue -= b * 0x00010000;
c = ipvalue >> 8;
ipvalue -= c * 0100000100;
d = ipvalue;
fprintf(stream, "%d.%d.%d.%d", d, c, b, a);
}
void PrintSocketAddress(const struct sockaddr * address, FILE * stream)
{
struct in_addr ip4addr;
in_port_t port;
struct sockaddr_in * ipv4Address;
if(address == NULL || stream == NULL)
{
return;
}
//printf("sa_family: %dn", address->sa_family);
switch(address->sa_family)
{
case AF_INET:
fputs("[IPv4] ", stream);
ipv4Address = (struct sockaddr_in *)address;
ip4addr = ipv4Address->sin_addr;
port = ntohs(ipv4Address->sin_port);
//fprintf(stream, "ip4addr.s_addr: %Xn", ip4addr.s_addr);
PrintIPv4(ip4addr.s_addr, stream);
fprintf(stream, " : %d", port);
break;
case AF_INET6:
fputs("[IPv6] ", stream);
break;
default:
fputs("[unknown type]", stream);
return;
}
}
void PrintTime(FILE * stream)
{
time_t currentTime;
struct tm * local_time;
struct timeval tv;
currentTime = time(0);
local_time = localtime(¤tTime);
gettimeofday(&tv);
fprintf(stream, "%04d-%02d-%02d %02d:%02d:%02d.%03d",
local_time->tm_year + 1900,
local_time->tm_mon + 1,
local_time->tm_mday,
local_time->tm_hour,
local_time->tm_min,
local_time->tm_sec,
tv.tv_usec / 1000);
}
int main(int argc, char * argv[])
{
char * serverPortString;
struct addrinfo addrCriteria;
struct addrinfo *serverAddr;
int socketHandle;
int returnValue;
struct sockaddr_storage clientAddr;
socklen_t clientAddrLen = sizeof(struct sockaddr);
char buffer[BUFFER_LENGTH];
ssize_t receivedBytesCount;
ssize_t sendBytesCount;
if(argc != 2)
{
//ExitWithMessage(0xF001, "Need parameter: <Server_Port>");
serverPortString = "2001";
}
else
{
// First argument: local port
serverPortString = argv[1];
}
memset(&addrCriteria, 0, sizeof(struct addrinfo));
addrCriteria.ai_family = AF_UNSPEC; // Any address family
addrCriteria.ai_flags = AI_PASSIVE; // Accept on any address/port
addrCriteria.ai_socktype = SOCK_DGRAM; // only datagram socket
addrCriteria.ai_protocol = IPPROTO_UDP; // only UDP socket
returnValue = getaddrinfo(NULL, serverPortString, &addrCriteria, &serverAddr);
if(returnValue != 0)
{
fprintf(stderr, "getaddrinfo() failed.n");
ExitWithMessage(returnValue, gai_strerror(returnValue));
}
// Create socket for incomming connections
socketHandle = socket(serverAddr->ai_family, serverAddr->ai_socktype, serverAddr->ai_protocol);
if(socketHandle < 0)
{
fprintf(stderr, "socket() failed.n");
ExitWithMessage(socketHandle, gai_strerror(socketHandle));
}
// Bind to local address
returnValue = bind(socketHandle, serverAddr->ai_addr, serverAddr->ai_addrlen);
if(returnValue < 0)
{
fprintf(stderr, "bind() failed.n");
ExitWithMessage(returnValue, gai_strerror(returnValue));
}
// Free address list allocated by getaddrinfo
freeaddrinfo(serverAddr);
printf("Starting the UDP Server ...n");
printf("Listinning at port %snn", serverPortString);
while(1)
{
receivedBytesCount = recvfrom(
socketHandle,
buffer,
BUFFER_LENGTH,
0,
(struct sockaddr *)&clientAddr,
&clientAddrLen);
// printf("Received %d bytes.n", receivedBytesCount);
if(receivedBytesCount < 0)
{
fprintf(stderr, "recvfrom() failed.n");
ExitWithMessage(receivedBytesCount, gai_strerror(receivedBytesCount));
}
fputs("Handling client ", stdout);
PrintSocketAddress((struct sockaddr *)&clientAddr, stdout);
fputs(" at ", stdout);
PrintTime(stdout);
fputc('n', stdout);
buffer[receivedBytesCount] = '