#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 ExitWithMessage(const int errorCode, const char * errorMessage)
{
fprintf(stderr, "\n\nError Msg : %s\n", errorMessage);
fprintf(stderr, "Error Code : 0x%X\n", errorCode);
fprintf(stderr, "Location : %s: %d\n\n", __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: %d\n", 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: %X\n", 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;
}
}
int main(int argc, char * argv[])
{
char * server;
char * serverPort;
char * echoString;
size_t echoStringLength;
struct addrinfo addrCriteria;
struct addrinfo *serverAddr;
int socketHandle;
int returnValue;
ssize_t receivedBytesCount;
ssize_t sendBytesCount;
struct sockaddr_storage responseAddr;
socklen_t responseAddrLen = sizeof(struct sockaddr);
char buffer[BUFFER_LENGTH + 1];
int broadcastPermission = 1;
if(argc < 3 || argc > 4)
{
ExitWithMessage(1, "Parameters: <Server_IPv4> <Server_Port> <Message>");
}
server = argv[1];
serverPort = argv[2];
echoString = argv[3];
echoStringLength = strlen(echoString);
if(echoStringLength >= BUFFER_LENGTH)
{
ExitWithMessage(2, "Message is too long.");
}
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(server, serverPort, &addrCriteria, &serverAddr);
if(returnValue != 0)
{
fprintf(stderr, "getaddrinfo() failed.\n");
ExitWithMessage(returnValue, gai_strerror(returnValue));
}
// Create a datagram/UDP socket
socketHandle = socket(serverAddr->ai_family, serverAddr->ai_socktype, serverAddr->ai_protocol);
if(socketHandle < 0)
{
fprintf(stderr, "socket() failed.\n");
ExitWithMessage(socketHandle, gai_strerror(socketHandle));
}
// Set socket to be allowed broadcast
returnValue = setsockopt(
socketHandle, SOL_SOCKET,
SO_BROADCAST,
(void *) &broadcastPermission,
sizeof(broadcastPermission));
if(returnValue != 0)
{
fprintf(stderr, "setsockopt() failed.\n");
ExitWithMessage(returnValue, gai_strerror(returnValue));
}
sendBytesCount = sendto(socketHandle, echoString, echoStringLength, 0, serverAddr->ai_addr, serverAddr->ai_addrlen);
if(sendBytesCount < 0)
{
fprintf(stderr, "sendto() failed.\n");
ExitWithMessage(sendBytesCount, gai_strerror(sendBytesCount));
}
// Receive a response
receivedBytesCount = recvfrom(
socketHandle,
buffer,
BUFFER_LENGTH,
0,
(struct sockaddr *)&responseAddr,
&responseAddrLen);
if(receivedBytesCount < 0)
{
fprintf(stderr, "recvfrom() failed.\n");
ExitWithMessage(receivedBytesCount, gai_strerror(receivedBytesCount));
}
fputs("Server address: ", stdout);
PrintSocketAddress((struct sockaddr *)&responseAddr, stdout);
buffer[receivedBytesCount] = '\0';
printf("\nResponse: %s\n", buffer);
freeaddrinfo(serverAddr);
return 0;
}
Socket tips: UDP Echo service - Client code
最新推荐文章于 2024-08-07 14:12:54 发布