Skip to content

Instantly share code, notes, and snippets.

@tostiheld
Last active December 16, 2015 19:35
Show Gist options
  • Select an option

  • Save tostiheld/3da2e4fc36abe44f64d2 to your computer and use it in GitHub Desktop.

Select an option

Save tostiheld/3da2e4fc36abe44f64d2 to your computer and use it in GitHub Desktop.
tcp client/server code
simple tcp client/server testing code
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
#include "Auxiliary.h"
#include "AcceptTCPConnection.h"
int AcceptTCPConnection (int servSock)
{
// 'servSock' is obtained from CreateTCPServerSocket()
int clntSock; /* Socket descriptor for client */
struct sockaddr_in echoClntAddr; /* Client address */
unsigned int clntLen; /* Length of client address data structure */
/* Set the size of the in-out parameter */
clntLen = sizeof (echoClntAddr);
/* Wait for a client to connect */
clntSock = accept (servSock, (struct sockaddr *) &echoClntAddr, &clntLen);
if (clntSock < 0)
{
DieWithError ("accept() failed");
}
/* clntSock is connected to a client! */
info_s ("accept", inet_ntoa (echoClntAddr.sin_addr));
info_set_local_peer (clntSock);
return (clntSock);
}
#ifndef _ACCEPT_TCP_CONNECTION_H_
#define _ACCEPT_TCP_CONNECTION_H_
extern int AcceptTCPConnection (int servSock); /* Accept TCP connection request */
#endif
#include <stdio.h>
#include <stdlib.h> // for atoi() and exit()
#include <string.h> // for strlen()
#include <arpa/inet.h> // for sockaddr_in and inet_ntoa()
#include <pthread.h> // for POSIX threads
#include <sys/socket.h> // for socket(), bind(), getsockname and connect()
#include <time.h> // for time()
#include <unistd.h> // for sleep(), close()
#include "Auxiliary.h"
#define MAX_DATA 10
char * argv_ip = NULL;
unsigned short argv_port = 0;
int argv_timeout = 1;
char * argv_tty = NULL;
int argv_forkmax = 0;
bool argv_verbose = false;
bool argv_delay = false;
bool argv_debug = false;
bool argv_userprefix = false;
int argv_nrofdata = 0;
char * argv_data[MAX_DATA] = { NULL };
static FILE * tty_fptr = NULL;
static char local_prefix [80] = { '\0' };
static char peer_prefix [80] = { '\0' };
void
delaying (void)
{
if (argv_delay == true)
{
sleep (1);
}
}
char *
remove_nl (char * s)
{
// remove the trailing nerwline in 's' (if present)
int len;
len = strlen (s);
if (s [len - 1] == '\n')
{
s [len - 1] = '\0';
}
return (s);
}
void
DieWithError (const char * errorMessage)
{
perror (errorMessage);
exit (1);
}
void
info_set_tty (const char * name)
{
char s[80];
tty_fptr = fopen (name, "w");
if (tty_fptr == NULL)
{
sprintf (s, "ERROR: unable to open '%s' for writing", name);
perror (s);
}
}
void
info_set_local_peer (int sock)
{
unsigned int len;
struct sockaddr_in a;
len = sizeof(a);
if (getsockname(sock, (struct sockaddr *) &a, &len) != 0)
{
DieWithError ("ERROR in getsockname()");
}
if (argv_verbose == true)
{
printf ("sock:\n");
printf (" family: %d\n", a.sin_family);
printf (" addr: %s\n", inet_ntoa(a.sin_addr));
printf (" port: %d\n", ntohl (a.sin_port));
}
sprintf (local_prefix, "LOCAL %s(%05d)", inet_ntoa(a.sin_addr), ntohl (a.sin_port));
len = sizeof(a);
if (getpeername(sock, (struct sockaddr *) &a, &len) != 0)
{
//perror ("getpeername()");
DieWithError ("ERROR in getpeername()");
}
if (argv_verbose == true)
{
printf ("peer:\n");
printf (" family: %d\n", a.sin_family);
printf (" addr: %s\n", inet_ntoa(a.sin_addr));
printf (" port: %d\n", ntohl (a.sin_port));
}
sprintf (peer_prefix, "PEER %s(%05d)", inet_ntoa(a.sin_addr), ntohl (a.sin_port));
}
void
info (const char * s)
{
struct timespec ts;
if (argv_verbose == true)
{
clock_gettime(CLOCK_REALTIME, &ts);
fprintf (stdout, "(%d,%lx) %3ld.%06ld %s\n",
getpid(),
pthread_self(),
ts.tv_sec%1000,
ts.tv_nsec/1000, s);
}
}
static void
info_user (const char * prefix, const char * s)
{
struct tm ti;
time_t t;
if (tty_fptr == NULL)
{
tty_fptr = stdout;
}
if (argv_userprefix == true)
{
if (time (&t) == -1)
{
DieWithError ("time()");
}
if (localtime_r (&t, &ti) == NULL)
{
DieWithError ("localtime()");
}
fprintf (tty_fptr, "%02d:%02d:%02d %s:> ",
ti.tm_hour,
ti.tm_min,
ti.tm_sec,
prefix);
}
fprintf (tty_fptr, "%s", s);
}
void
info_local (const char * s)
{
info_user (local_prefix, s);
}
void
info_peer (const char * s)
{
info_user (peer_prefix, s);
}
void
info_d (const char * s, int i)
{
char str[80];
sprintf (str, "%s: %d", s, i);
info (str);
}
void
info_x (const char * s, unsigned int i)
{
char str[80];
sprintf (str, "%s: %x", s, i);
info (str);
}
void
info_s (const char * s, const char * i)
{
char str[80];
sprintf (str, "%s '%s'", s, i);
info (str);
}
void parse_args (int argc, char *argv[])
{
int opt;
int i;
while ((opt = getopt(argc, argv, "i:t:p:y:f:uvdgh")) != -1)
{
switch (opt)
{
case 'i':
argv_ip = optarg;
break;
case 'y':
argv_tty = optarg;
info_set_tty (argv_tty);
break;
case 'p':
argv_port = atoi(optarg);
break;
case 't':
argv_timeout = atoi(optarg);
break;
case 'f':
argv_forkmax = atoi(optarg);
break;
case 'v':
argv_verbose = true;
break;
case 'u':
argv_userprefix = true;
break;
case 'd':
argv_delay = true;
break;
case 'g':
argv_debug = true;
break;
case '?':
case 'h':
printf("\noptions: \n"
" -i <ip> \n"
" -y <tty-name> \n"
" -t <timeout> \n"
" -p <port> \n"
" -f <fork-max>\n"
" -d delay operation\n"
" -g debug info\n"
" -u user prefix\n"
" -v verbose\n"
" <data>*\n"
"\n");
exit(0);
break;
default:
fprintf(stderr, "ERROR: unknown option '%c'\n", opt);
exit(1);
break;
}
}
for (i = 0; (i < MAX_DATA) && (optind < argc); i++, optind++)
{
argv_data[i] = argv [optind];
}
argv_nrofdata = i;
if (argv_debug == true)
{
printf ("\ncompiler version: %s\n\n", __VERSION__);
printf ("user settings:\n"
" ip: %s\n"
" port: %d\n"
" tty: %s\n"
" timeout: %d\n"
" verbose: %s\n"
" delay: %s\n"
" debug: %s\n"
" userprefix:%s\n"
" data(%d): ",
argv_ip, argv_port, argv_tty, argv_timeout,
argv_verbose?"true":"false",
argv_delay?"true":"false",
argv_debug?"true":"false",
argv_userprefix?"true":"false",
argv_nrofdata);
for (i = 0; i < argv_nrofdata; i++)
{
printf ("'%s' ", argv_data [i]);
}
printf ("\n");
}
}
#ifndef _AUXILIARY_H_
#define _AUXILIARY_H_
#include <stdbool.h> /* for bool,true,false */
extern char * argv_ip;
extern unsigned short argv_port;
extern int argv_timeout;
extern int argv_forkmax;
//extern char * argv_tty;
//extern bool argv_verbose;
//extern bool argv_debug;
//extern bool argv_delay;
//extern bool argv_userprefix;
extern int argv_nrofdata;
extern char * argv_data[];
extern void delaying (void);
extern void DieWithError(const char * errorMessage); /* Error handling function */
extern void info (const char * s);
extern void info_d (const char * s, int d);
extern void info_x (const char * s, unsigned int d);
extern void info_s (const char * s, const char * d);
extern void info_peer (const char * s);
extern void info_local (const char * s);
extern void info_set_output (const char * name);
extern void info_set_local_peer (int sock);
extern char * remove_nl (char * s);
extern void parse_args (int argc, char * argv[]);
#endif
#!/bin/bash
#CCC="i586-linux-g++"
CCC="g++"
FLAGS="-Wall -W -Wshadow -Wcast-qual -Wwrite-strings"
for i in $(ls *.c); do
echo `basename $i .c`.o
$CCC -o `basename $i .c`.o -g3 -c $FLAGS $i || exit
done
echo
for i in $(ls T*.o); do
echo `basename $i .o`
$CCC -o `basename $i .o` $i A*.o C*.o H*.o -lrt $FLAGS || exit
done
#include <memory.h> // for memset()
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
#include "Auxiliary.h"
#include "CreateTCPClientSocket.h"
int CreateTCPClientSocket (const char * servIP, unsigned short port)
{
int sock; /* Socket descriptor */
struct sockaddr_in echoServAddr; /* Echo server address */
/* Create a reliable, stream socket using TCP */
if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
DieWithError("socket() failed");
}
info ("socket");
delaying ();
/* Construct the server address structure */
memset(&echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet address family */
echoServAddr.sin_addr.s_addr = inet_addr(servIP); /* Server IP address */
echoServAddr.sin_port = htons(port); /* Server port */
/* Establish the connection to the echo server */
if (connect(sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
{
DieWithError("connect() failed");
}
info ("connect");
info_set_local_peer (sock);
return (sock);
}
#ifndef _CREATE_TCP_CLIENT_SOCKET_H_
#define _CREATE_TCP_CLIENT_SOCKET_H_
extern int CreateTCPClientSocket (const char * addr, unsigned short port); /* Create TCP server socket */
#endif
#include <memory.h> // for memset()
#include <arpa/inet.h> /* for sockaddr_in and inet_ntoa() */
#include "Auxiliary.h"
#include "CreateTCPServerSocket.h"
#define MAXPENDING 5 /* Maximum outstanding connection requests */
int CreateTCPServerSocket (unsigned short port)
{
int sock; /* socket to create */
struct sockaddr_in echoServAddr; /* Local address */
/* Create socket for incoming connections */
if ((sock = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
DieWithError ("socket() failed");
}
info ("socket");
/* Construct local address structure */
memset( &echoServAddr, 0, sizeof(echoServAddr)); /* Zero out structure */
echoServAddr.sin_family = AF_INET; /* Internet address family */
echoServAddr.sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming interface */
echoServAddr.sin_port = htons(port); /* Local port */
/* Bind to the local address */
if (bind (sock, (struct sockaddr *) &echoServAddr, sizeof(echoServAddr)) < 0)
{
DieWithError ("bind() failed");
}
info_d ("bind", port);
/* Mark the socket so it will listen for incoming connections */
if (listen (sock, MAXPENDING) < 0)
{
DieWithError ("listen() failed");
}
info ("listen");
return (sock);
}
#ifndef _CREATE_TCP_SERVER_SOCKET_H_
#define _CREATE_TCP_SERVER_SOCKET_H_
extern int CreateTCPServerSocket (unsigned short port); /* Create TCP server socket */
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#ifndef NI_MAXHOST
#define NI_MAXHOST 1025
#endif // NI_MAX_HOST
#define E(e) { #e, e }
typedef struct
{
const char * name;
int nr;
} ENUM_t;
static ENUM_t socket_enum[] = { E(SOCK_STREAM), E(SOCK_DGRAM), E(SOCK_RAW), E(-1) };
static ENUM_t family_enum[] = { E(PF_INET), E(-1) };
static char *
print_enum (int val, ENUM_t lut[])
{
int i = 0;
static char str[80];
while (1)
{
if ((lut[i].nr == -1) && (strcmp (lut[i].name, "-1") == 0))
{
sprintf (str, "unknown [%d,%#x]", val, val);
return (str);
}
if (lut[i].nr == val)
{
sprintf (str, "%d %s", lut[i].nr, lut[i].name);
return (str);
}
i++;
}
}
static void
print_protocol (int n)
{
struct protoent * p;
char ** a;
p = getprotobynumber (n);
printf ("ai_protocol: %d %s", p->p_proto, p->p_name);
if (p->p_aliases != NULL)
{
printf (" [aliases:");
a = p->p_aliases;
while ((a != NULL) && (*a != NULL))
{
printf (" '%s'", *a);
a++;
}
printf ("]");
}
printf ("\n");
}
static void
print_sockaddr_in (struct sockaddr_in * a)
{
printf (" sin_family: %s\n", print_enum (a->sin_family, family_enum));
printf (" sin_addr: %s\n", inet_ntoa (a->sin_addr));
printf (" sin_port: %d\n", ntohl (a->sin_port));
}
int main(int argc, char * argv[])
{
struct addrinfo * result;
size_t hostname_len = NI_MAXHOST;
char hostname[NI_MAXHOST];
int error;
if (argc != 2)
{
fprintf (stderr, "Usage: %s <URL>\n", argv[0]);
exit (1);
}
error = getaddrinfo(argv[1], NULL, NULL, &result);
if (error != 0)
{
fprintf(stderr, "error using getaddrinfo: %s\n", gai_strerror(error));
exit (1);
}
while (result != NULL)
{
printf ("ai_flags: %d\n", result->ai_flags);
printf ("ai_family: %s\n", print_enum (result->ai_family, family_enum));
printf ("ai_socktype: %s\n", print_enum (result->ai_socktype, socket_enum));
//printf ("ai_protocol: %d\n", result->ai_protocol);
print_protocol (result->ai_protocol);
print_sockaddr_in ((struct sockaddr_in *) result->ai_addr);
printf ("ai_canonname: '%s'\n", result->ai_canonname);
error = getnameinfo(result->ai_addr, result->ai_addrlen, hostname, hostname_len, NULL, 0, 0);
if (error != 0)
{
fprintf(stderr, "error using getaddrinfo: %s\n", gai_strerror(error));
break;
}
printf ("name : '%s'\n", hostname);
result = result->ai_next;
printf ("\n");
}
// TODO: free!!!!!
return (0);
}
#include <stdio.h>
#include <ctype.h> // for isupper() etc.
#include <sys/socket.h> // for send() and recv()
#include <unistd.h> // for sleep(), close()
#include "Auxiliary.h"
#include "HandleTCPClient.h"
#define RCVBUFSIZE 32 /* Size of receive buffer */
void HandleTCPClient (int clntSocket)
{
// 'clntSocket' is obtained from AcceptTCPConnection()
char echoBuffer[RCVBUFSIZE]; /* Buffer for echo string */
int recvMsgSize; /* Size of received message */
/* Receive message from client */
recvMsgSize = recv (clntSocket, echoBuffer, RCVBUFSIZE-1, 0);
if (recvMsgSize < 0)
{
printf("recv() failed");
}
/* Send received string and receive again until end of transmission */
while (recvMsgSize > 0) /* zero indicates end of transmission */
{
echoBuffer[recvMsgSize] = '\0';
/* Echo message back to client */
if (send (clntSocket, echoBuffer, recvMsgSize, 0) != recvMsgSize)
{
DieWithError ("send() failed");
}
// receive next string
recvMsgSize = recv (clntSocket, echoBuffer, RCVBUFSIZE-1, 0);
if (recvMsgSize < 0)
{
DieWithError ("recv() failed");
}
}
close (clntSocket); /* Close client socket */
}
#ifndef _HANDLE_TCP_CLIENT_H_
#define _HANDLE_TCP_CLIENT_H_
extern void HandleTCPClient (int clntSocket); /* TCP client handling function */
#endif
#
# Makefile for IPC32
#
# (c) Fontys 2010, Joris Geurts
#
BINARIES = TCPEchoClient TCPEchoServer
#CC = i586-linux-g++
CC = g++
CFLAGS = -g3 -Wall -W -Wshadow -Wcast-qual -Wwrite-strings
LDLIBS =
CLIENT_AUX_OBJS = Auxiliary.o CreateTCPClientSocket.o
SERVER_AUX_OBJS = Auxiliary.o CreateTCPServerSocket.o AcceptTCPConnection.o HandleTCPClient.o
all: $(BINARIES)
clean:
rm *.o $(BINARIES)
TCPEchoClient: TCPEchoClient.o $(CLIENT_AUX_OBJS)
TCPEchoServer: TCPEchoServer.o $(SERVER_AUX_OBJS)
#include <stdio.h>
#include <string.h> // for strlen()
#include <stdlib.h> // for exit()
#include <sys/socket.h> // for send() and recv()
#include <unistd.h> // for sleep(), close()
#include <sys/time.h>
#include "CreateTCPClientSocket.h"
#define RCVBUFSIZE 32 /* Size of receive buffer */
#define TEST_COUNT 1000
int main ()
{
int sock; /* Socket descriptor */
char echoBuffer[RCVBUFSIZE]; /* Buffer for received string */
printf("started\n");
sock = CreateTCPClientSocket ("192.168.1.100", 4242);
printf("socket created\n");
unsigned long averages[TEST_COUNT];
unsigned long full_total;
int samplesize = 100;
for (int i = 0; i < TEST_COUNT; i++)
{
unsigned long run_total;
//printf("run %i started\n", i);
for (int j = 0; j < samplesize; j++)
{
timeval time_before;
gettimeofday(&time_before, NULL);
char string[] = "hoi";
send(sock, string, strlen(string), 0);
recv(sock, echoBuffer, RCVBUFSIZE - 1, 0);
timeval time_after;
gettimeofday(&time_after, NULL);
run_total += time_after.tv_usec - time_before.tv_usec;
}
averages[i] = run_total / samplesize;
full_total += run_total / samplesize;
//printf("run %i completed\n", i);
}
unsigned long full_average = full_total / TEST_COUNT;
printf("Averages:\n\n");
for (int i = 0; i < TEST_COUNT; i++)
{
printf("%ld\n", averages[i]);
}
printf("\nFull average: %ld us\n", full_average);
close (sock);
exit (0);
}
#include "Auxiliary.h"
#include "AcceptTCPConnection.h"
#include "CreateTCPServerSocket.h"
#include "HandleTCPClient.h"
int main (int argc, char * argv[])
{
int servSock; /* Socket descriptor for server */
int clntSock; /* Socket descriptor for client */
parse_args (argc, argv);
servSock = CreateTCPServerSocket (4242);
for (;;) /* Run forever */
{
clntSock = AcceptTCPConnection (servSock);
HandleTCPClient (clntSock);
}
/* NOT REACHED */
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment