Skip to content

Instantly share code, notes, and snippets.

@jsuwo
Last active November 9, 2015 04:32
Show Gist options
  • Save jsuwo/dc02f8332df2eaae5b55 to your computer and use it in GitHub Desktop.
Save jsuwo/dc02f8332df2eaae5b55 to your computer and use it in GitHub Desktop.
Code samples from Computer Networks I Lab Manual, Chapter 5 - UDP Socket Programming
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "udp_client.h"
#include "udp_sockets.h"
int main()
{
host server; // Server address
message* msg; // Message to send/receive
// Create a socket for communication with the server
int sockfd = create_client_socket("localhost", "5000", &server);
// Create a message, and initialize its contents
msg = create_message();
msg->length = strlen("hello");
memcpy(msg->buffer, "hello", msg->length);
// Send the message to the server, and free its memory
int retval = send_message(sockfd, msg, &server);
free(msg);
// If we couldn't send the message, exit the program
if (retval == -1)
{
close(sockfd);
perror("Unable to send to socket");
exit(EXIT_FAILURE);
}
// Read the server's reply
msg = receive_message(sockfd, &server);
if (msg != NULL)
{
// Add NULL terminator and print reply
msg->buffer[msg->length] = '\0';
printf("Reply from server %s: %s\n", server.friendly_ip, msg->buffer);
// Free the memory allocated to the message
free(msg);
}
// Close the socket
close(sockfd);
exit(EXIT_SUCCESS);
}
#include <arpa/inet.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include "udp_sockets.h"
#include "udp_server.h"
int main()
{
int bytes_read; // Number of bytes read
char buffer[65535]; // Buffer to store incoming message
char ip_address[INET_ADDRSTRLEN]; // Buffer to store human-readable source IP address
struct sockaddr_in addr; // Source address and port
socklen_t addr_len = sizeof(struct sockaddr_in); // Length of the addr structure
// Create a socket to listen on port 5000
int sockfd = create_server_socket("5000");
// Read the next message into buffer, storing the source address in addr
bytes_read = recvfrom(sockfd, buffer, sizeof(buffer), 0, (struct sockaddr*)&addr, &addr_len);
// Convert the source address to a human-readable IP address
inet_ntop(addr.sin_family, &addr.sin_addr, ip_address, sizeof(ip_address));
if (bytes_read > 0)
{
// Add NULL terminator
buffer[bytes_read] = '\0';
printf("Message received from %s: %s\n", ip_address, buffer);
}
// Close the socket
close(sockfd);
exit(EXIT_SUCCESS);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "udp_sockets.h"
#include "udp_server.h"
int main()
{
message* msg; // Message received
host source; // Source of the message received
// Create a socket to listen on port 5000
int sockfd = create_server_socket("5000");
// Read the next message
msg = receive_message(sockfd, &source);
if (msg != NULL)
{
// Add NULL terminator
msg->buffer[msg->length] = '\0';
printf("Message received from %s: %s\n", source.friendly_ip, msg->buffer);
}
// Free the memory allocated to the message
free(msg);
// Close the socket
close(sockfd);
exit(EXIT_SUCCESS);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "udp_sockets.h"
#include "udp_server.h"
int main()
{
message* msg; // Message received
host source; // Source of the message received
// Create a socket to listen on port 5000
int sockfd = create_server_socket("5000");
// Read the next message
msg = receive_message(sockfd, &source);
if (msg != NULL)
{
// Add NULL terminator
msg->buffer[msg->length] = '\0';
printf("Message received from %s: %s\n", source.friendly_ip, msg->buffer);
// Echo the message back to the client
if (sendto(sockfd, msg->buffer, msg->length, 0,
(struct sockaddr*)&source.addr, source.addr_len) == -1)
{
free(msg);
perror("Unable to send to socket");
exit(EXIT_FAILURE);
}
}
// Free the memory allocated to the message
free(msg);
// Close the socket
close(sockfd);
exit(EXIT_SUCCESS);
}
CC=gcc
CFLAGS=-Wall -Werror -std=gnu11 -g -c
LFLAGS=-Wall -Werror -g
all: fig5-3 fig5-4 fig5-5 server client
fig5-3: fig5-3.o udp_sockets.o udp_server.o
$(CC) $(LFLAGS) -o $@ $^
fig5-4: fig5-4.o udp_sockets.o udp_server.o
$(CC) $(LFLAGS) -o $@ $^
fig5-5: fig5-5.o udp_sockets.o udp_server.o
$(CC) $(LFLAGS) -o $@ $^
server: server.o udp_sockets.o udp_server.o
$(CC) $(LFLAGS) -o $@ $^
client: client.o udp_sockets.o udp_client.o
$(CC) $(LFLAGS) -o $@ $^
fig5-3.o: fig5-3.c udp_server.h udp_sockets.h
$(CC) $(CFLAGS) -o $@ $<
fig5-4.o: fig5-4.c udp_server.h udp_sockets.h
$(CC) $(CFLAGS) -o $@ $<
fig5-5.o: fig5-5.c udp_server.h udp_sockets.h
$(CC) $(CFLAGS) -o $@ $<
server.o: server.c udp_server.h udp_sockets.h
$(CC) $(CFLAGS) -o $@ $<
client.o: client.c udp_client.h udp_sockets.h
$(CC) $(CFLAGS) -o $@ $<
udp_sockets.o: udp_sockets.c udp_sockets.h
$(CC) $(CFLAGS) -o $@ $<
udp_server.o: udp_server.c udp_server.h udp_sockets.h
$(CC) $(CFLAGS) -o $@ $<
udp_client.o: udp_client.c udp_client.h udp_sockets.h
$(CC) $(CFLAGS) -o $@ $<
clean:
rm -f *.o fig5-3 fig5-4 fig5-5 server client
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "udp_sockets.h"
#include "udp_server.h"
int main()
{
message* msg; // Message received
host source; // Source of the message received
// Create a socket to listen on port 5000
int sockfd = create_server_socket("5000");
// Read the next message
msg = receive_message(sockfd, &source);
if (msg != NULL)
{
// Add NULL terminator
msg->buffer[msg->length] = '\0';
printf("Message received from %s: %s\n", source.friendly_ip, msg->buffer);
// Echo the message back to the client
if (send_message(sockfd, msg, &source) == -1)
{
free(msg);
perror("Unable to send to socket");
exit(EXIT_FAILURE);
}
}
// Free the memory allocated to the message
free(msg);
// Close the socket
close(sockfd);
exit(EXIT_SUCCESS);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "udp_client.h"
int create_client_socket(char* hostname, char* port, host* server)
{
int sockfd;
struct addrinfo* addr;
struct addrinfo* results = get_udp_sockaddr(hostname, port, 0);
// Iterate through each addrinfo in the list;
// stop when we successfully create a socket
for (addr = results; addr != NULL; addr = addr->ai_next)
{
// Open a socket
sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
// Try the next address if we couldn't open a socket
if (sockfd == -1)
continue;
// Copy server address and length to the out parameter 'server'
memcpy(&server->addr, addr->ai_addr, addr->ai_addrlen);
memcpy(&server->addr_len, &addr->ai_addrlen, sizeof(addr->ai_addrlen));
// We've successfully created a socket; stop iterating
break;
}
// Free the memory allocated to the addrinfo list
freeaddrinfo(results);
// If we tried every addrinfo and failed to create a socket
if (addr == NULL)
{
perror("Unable to create socket");
exit(EXIT_FAILURE);
}
else
{
// Otherwise, return the socket descriptor
return sockfd;
}
}
#include "udp_sockets.h"
#ifndef UDP_CLIENT_H
#define UDP_CLIENT_H
int create_client_socket(char* hostname, char* port, host* server);
#endif
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <unistd.h>
#include "udp_server.h"
#include "udp_sockets.h"
int bind_socket(struct addrinfo* addr_list)
{
struct addrinfo* addr;
int sockfd;
// Iterate through each addrinfo in the list; stop when we successfully bind
// to one
for (addr = addr_list; addr != NULL; addr = addr->ai_next)
{
// Open a socket
sockfd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
// Try the next address if we couldn't open a socket
if (sockfd == -1)
continue;
// Try to bind the socket to the address/port
if (bind(sockfd, addr->ai_addr, addr->ai_addrlen) == -1)
{
// If binding fails, close the socket, and try the next address
close(sockfd);
continue;
}
else
{
// Otherwise, we've bound the address/port to the socket, so stop
// processing
break;
}
}
// Free the memory allocated to the addrinfo list
freeaddrinfo(addr_list);
// If addr is NULL, we tried every addrinfo and weren't able to bind to any
if (addr == NULL)
{
perror("Unable to bind");
exit(EXIT_FAILURE);
}
else
{
// Otherwise, return the socket descriptor
return sockfd;
}
}
int create_server_socket(char* port)
{
struct addrinfo* results = get_udp_sockaddr(NULL, port, AI_PASSIVE);
int sockfd = bind_socket(results);
return sockfd;
}
#include <netdb.h>
#ifndef UDP_SERVER_H
#define UDP_SERVER_H
int bind_socket(struct addrinfo* addr_list);
int create_server_socket(char* port);
#endif
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "udp_sockets.h"
struct addrinfo* get_udp_sockaddr(const char* node, const char* port, int flags)
{
struct addrinfo hints;
struct addrinfo* results;
int retval;
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET; // Return socket addresses for our local IPv4 addresses
hints.ai_socktype = SOCK_DGRAM; // Return UDP socket addresses
hints.ai_flags = flags; // Socket addresses should be listening sockets
retval = getaddrinfo(node, port, &hints, &results);
if (retval != 0)
{
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(retval));
exit(EXIT_FAILURE);
}
return results;
}
message* create_message()
{
return (message*)malloc(sizeof(message));
}
message* receive_message(int sockfd, host* source)
{
message* msg = create_message();
// Length of the remote IP structure
source->addr_len = sizeof(source->addr);
// Read message, storing its contents in msg->buffer, and
// the source address in source->addr
msg->length = recvfrom(sockfd, msg->buffer, sizeof(msg->buffer), 0,
(struct sockaddr*)&source->addr,
&source->addr_len);
// If a message was read
if (msg->length > 0)
{
// Convert the source address to a human-readable form,
// storing it in source->friendly_ip
inet_ntop(source->addr.sin_family, &source->addr.sin_addr,
source->friendly_ip, sizeof(source->friendly_ip));
// Return the message received
return msg;
}
else
{
// Otherwise, free the allocated memory and return NULL
free(msg);
return NULL;
}
}
int send_message(int sockfd, message* msg, host* dest)
{
return sendto(sockfd, msg->buffer, msg->length, 0,
(struct sockaddr*)&dest->addr, dest->addr_len);
}
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#ifndef UDP_SOCKETS_H
#define UDP_SOCKETS_H
#define UDP_MSS 65535
typedef struct
{
int length;
uint8_t buffer[UDP_MSS];
} message;
typedef struct
{
struct sockaddr_in addr;
socklen_t addr_len;
char friendly_ip[INET_ADDRSTRLEN];
} host;
struct addrinfo* get_udp_sockaddr(const char* node, const char* port, int flags);
message* create_message();
message* receive_message(int sockfd, host* source);
int send_message(int sockfd, message* msg, host* dest);
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment