Created
June 7, 2017 14:54
-
-
Save herry13/194774db850dcc3e6ffbe37e9cd108f8 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // | |
| // To compile: | |
| // gcc -Wall -pedantic -O3 -fomit-frame-pointer -o agent udp.c | |
| // | |
| #include <unistd.h> | |
| #include <sys/socket.h> | |
| #include <arpa/inet.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include <stdlib.h> | |
| #define SERVICE_PORT 9999 | |
| #define BUFSIZE 2048 | |
| extern int errno; | |
| /** | |
| * Create and return a socket handler for given port number. | |
| * | |
| * Param: | |
| * port - the port which the socket will be opened. If it equals | |
| * to 0, then a random port will be assigned to the socket. | |
| * | |
| * Return: a socket handler, or -1 if socket creation fails | |
| */ | |
| int create_udp_socket(const int & port) { | |
| int sock; | |
| struct sockaddr_in addr; | |
| // create an udp socket | |
| if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { | |
| perror("cannot create socket\n"); | |
| return -1; | |
| } | |
| // set up our address | |
| memset(&addr, 0, sizeof(addr)); | |
| addr.sin_len = sizeof(addr); | |
| addr.sin_family = AF_INET; | |
| addr.sin_port = htons(port); | |
| addr.sin_addr.s_addr = INADDR_ANY; // bind it to all local addresses | |
| // bind the server to the address | |
| if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { | |
| perror("socket binding failed\n"); | |
| return -1; | |
| } | |
| return sock; | |
| } | |
| /** | |
| * Listen any message on given port and then print it to standard output. | |
| * | |
| * Param: | |
| * port - the port which the server will listen to | |
| */ | |
| void serve(const int& port) { | |
| int sock; | |
| struct sockaddr_in client_addr; | |
| socklen_t addrlen = sizeof(client_addr); | |
| int recvlen; | |
| unsigned char buf[BUFSIZE]; | |
| char hostname[128]; | |
| // get server's hostname | |
| gethostname(hostname, 128); | |
| // create an udp socket | |
| sock = create_udp_socket(port); | |
| if (sock == -1) return; | |
| printf("server started on %s, listening on port %d\n", hostname, port); | |
| // loop forever, waiting for connection requests and process the message | |
| while (true) { | |
| recvlen = recvfrom(sock, buf, BUFSIZE, 0, (struct sockaddr *)&client_addr, | |
| &addrlen); | |
| if (recvlen > 0) { | |
| buf[recvlen] = 0; | |
| printf("received message: %s\nfrom:%s port:%d\n", | |
| buf, | |
| inet_ntoa(client_addr.sin_addr), | |
| ntohs(client_addr.sin_port)); | |
| } | |
| } | |
| } | |
| /** | |
| * Send a message to given address and port. | |
| * | |
| * Param: | |
| * message - a message to be sent | |
| * address - destination IP address | |
| * port - destination port number | |
| * | |
| * Return: 0 if it is successful, otherwise non-zero integer | |
| */ | |
| int send(const char *message, const char *address, const int port) { | |
| int sock; | |
| int i; | |
| struct sockaddr_in server_addr; | |
| socklen_t addrlen = sizeof(server_addr); | |
| char buf[BUFSIZE]; | |
| // create an udp socket | |
| sock = create_udp_socket(0); | |
| if (sock == -1) return -1; | |
| // Set up server's address to whom we want to send messages. | |
| // The address is expressed as a numeric IPv4 address that we will | |
| // convert to a binary format using inet_aton | |
| memset(&server_addr, 0, sizeof(server_addr)); | |
| server_addr.sin_family = AF_INET; | |
| server_addr.sin_port = htons(port); | |
| if (inet_aton(address, &server_addr.sin_addr) == 0) { | |
| perror("inet_atom() failed\n"); | |
| return 1; | |
| } | |
| // now, send the message 5 times | |
| for (i = 0; i < 5; i++) { | |
| sprintf(buf, "{\"id\":%d,\"message\":\"%s\"}", i, message); | |
| printf("sending packet %d to %s port %d\nmessage: %s\n", | |
| i, address, port, buf); | |
| if (sendto(sock, buf, strlen(buf), 0, (struct sockaddr *)&server_addr, | |
| addrlen) < 0) { | |
| perror("sendto() failed\n"); | |
| } | |
| } | |
| close(sock); | |
| return 0; | |
| } | |
| int main(int argc, char **argv) { | |
| extern char *optarg; | |
| extern int optind; | |
| int c, err = 0; | |
| int port = SERVICE_PORT; | |
| char * message = NULL; | |
| char buf[BUFSIZE]; | |
| char address[20]; | |
| sprintf(address, "127.0.0.1"); | |
| while ((c = getopt(argc, argv, "c:a:p:h")) != -1) { | |
| switch (c) { | |
| case 'c': | |
| message = optarg; | |
| if (strlen(message) <= 0) { | |
| perror("empty message\n"); | |
| err = 1; | |
| } | |
| break; | |
| case 'a': | |
| sprintf(address, "%s", optarg); | |
| if (strlen(address) <= 0) { | |
| perror("empty address\n"); | |
| err = 2; | |
| } | |
| break; | |
| case 'p': | |
| port = atoi(optarg); | |
| if (port < 1024 || port > 65535) { | |
| sprintf(buf, "invalid port number: %d\n", port); | |
| perror(buf); | |
| err = 3; | |
| } | |
| break; | |
| case 'h': | |
| case '?': | |
| err = 4; | |
| break; | |
| } | |
| } | |
| if (err != 0 || (optind < argc)) { | |
| printf("usage: %s [-c message] [-a address] [-p port]\n", argv[0]); | |
| return 1; | |
| } | |
| if (message == NULL) | |
| serve(port); | |
| else | |
| send(message, address, port); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment