Socket tips: UDP Echo service - Client code
#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; }
版权声明:本文博主原创文章,博客,未经同意不得转载。