Skip to content

Instantly share code, notes, and snippets.

@huzhifeng
Last active July 27, 2017 11:52
Show Gist options
  • Save huzhifeng/cd9b9bf36e52433d6e48c366f12bf23a to your computer and use it in GitHub Desktop.
Save huzhifeng/cd9b9bf36e52433d6e48c366f12bf23a to your computer and use it in GitHub Desktop.
UDP latency test (Based on https://www.abc.se/~m6695/udp.html)
#ifndef _COMMON_H
#define MAX_IP_LEN 16
#define MAX_TIME_LEN 32
#define MAX_DATA_LEN 64
/* 6ms */
#define MAX_LATENCY (60 * 1000)
typedef struct _packet {
unsigned long long sid;
unsigned long long ts;
char msg[MAX_DATA_LEN];
} packet;
char *microsecond2time(char *buf, unsigned long long ts)
{
unsigned long long sec = ts / 1000 / 1000;
unsigned long long msec = (ts - sec * 1000 * 1000) / 1000;
unsigned long long usec = (ts - sec * 1000 * 1000) % 1000;
char time[MAX_TIME_LEN] = { 0x0 };
struct tm *ptm = NULL;
if (NULL == buf) {
return NULL;
}
ptm = localtime((time_t *)&sec);
strftime(time, MAX_TIME_LEN, "%Y-%m-%d %H:%M:%S", ptm);
sprintf(buf, "[%s:%03d:%03d]", time, msec, usec);
return buf;
}
#endif
CC = gcc
CFLAGS = -O2 -g -Wall
INSTALL_DIR = /usr/bin
.PHONY: clean install uninstall
all: server client
server: udp-server.c
$(CC) udp-server.c -o udp-server
client: udp-client.c
$(CC) udp-client.c -o udp-client
clean:
rm -f *.o udp-server udp-client
install: server client
cp -f udp-server udp-client $(INSTALL_DIR)/
uninstall:
rm -f $(INSTALL_DIR)/udp-server $(INSTALL_DIR)/udp-client
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include "common.h"
static void print_help(const char *program)
{
printf("Version: %s %s\n", __DATE__, __TIME__);
printf("Usage: %s <ip> [port]\n", program);
printf(" ip server IP for connecting\n");
printf(" port UDP port for communicating (default is 2017)\n");
printf(" -h, --help display this help and exit\n");
printf("\nExample:\n");
printf(" %s 192.168.1.1\n", program);
printf(" %s 192.168.1.1 2017\n", program);
}
int main(int argc, char *argv[])
{
int s = 0; /* UDP socket descriptor */
int port = 2017; /* UDP port (default) */
unsigned long long sid = 0; /* UDP packet sequence id */
char ip[MAX_IP_LEN] = ""; /* Server IP */
packet pkt;
struct sockaddr_in si;
struct timeval tv;
struct timezone tz;
if (argc == 2) {
if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
print_help(argv[0]);
exit(0);
} else {
strncpy(ip, argv[1], MAX_IP_LEN); /* FIXME: verify ip address */
}
} else if (argc == 3) {
strncpy(ip, argv[1], MAX_IP_LEN); /* FIXME: verify ip address */
port = atoi(argv[2]); /* FIXME: verify port number */
} else {
print_help(argv[0]);
exit(0);
}
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
fprintf(stderr, "Failed to create socket\n");
exit(1);
}
memset(&si, 0x0, sizeof(si));
si.sin_family = AF_INET;
si.sin_port = htons(port);
if (inet_aton(ip, &si.sin_addr) == 0) {
fprintf(stderr, "Failed to inet_aton with %s:%d\n", ip, port);
exit(1);
}
while (1) {
sid++;
gettimeofday(&tv, &tz);
memset(&pkt, 0x0, sizeof(pkt));
pkt.sid = sid;
pkt.ts = tv.tv_sec * 1000 * 1000 + tv.tv_usec;
microsecond2time(pkt.msg, pkt.ts);
sprintf(pkt.msg, "%s-[%08llu]", pkt.msg, sid);
printf("%s\n", pkt.msg);
if (sendto(s, &pkt, sizeof(pkt), 0, (struct sockaddr *)&si,\
sizeof(struct sockaddr_in)) == -1) {
fprintf(stderr, "Failed to send [%s] to %s:%d\n", pkt.msg, ip, port);
close(s);
exit(1);
}
}
close(s);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include "common.h"
static void print_help(const char *program)
{
printf("Version: %s %s\n", __DATE__, __TIME__);
printf("Usage: %s [port]\n", program);
printf(" port UDP port for binding and listening (default is 2017)\n");
printf(" -h, --help display this help and exit\n");
printf("\nExample:\n");
printf(" %s\n", program);
printf(" %s 2017\n", program);
}
int main(int argc, char *argv[])
{
int s = 0; /* UDP socket descriptor */
int port = 2017; /* UDP port */
unsigned long long last_sid = 0;
unsigned long long ts = 0;
char time[MAX_TIME_LEN] = { 0x0 };
socklen_t addrlen;
struct sockaddr_in si_server, si_client;
packet pkt;
struct timeval tv;
struct timezone tz;
if (argc == 2) {
if ((strcmp(argv[1], "-h") == 0) || (strcmp(argv[1], "--help") == 0)) {
print_help(argv[0]);
exit(0);
} else {
port = atoi(argv[2]); /* FIXME: verify port number */
}
} else if (argc != 1) {
print_help(argv[0]);
exit(0);
}
printf("Starting...\n");
if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
fprintf(stderr, "Failed to create socket\n");
exit(1);
}
memset(&si_server, 0x0, sizeof(si_server));
si_server.sin_family = AF_INET;
si_server.sin_port = htons(port);
si_server.sin_addr.s_addr = htonl(INADDR_ANY);
if (bind(s, (struct sockaddr *)&si_server, sizeof(struct sockaddr)) == -1) {
fprintf(stderr, "Failed to bind with port %d\n", port);
exit(1);
}
while (1) {
memset(&pkt, 0x0, sizeof(pkt));
if (recvfrom(s, &pkt, sizeof(pkt), 0, \
(struct sockaddr *)&si_client, &addrlen) == -1) {
fprintf(stderr, "Failed to recvfrom\n");
close(s);
exit(1);
}
gettimeofday(&tv, &tz);
memset(time, 0x0, sizeof(time));
ts = tv.tv_sec * 1000 * 1000 + tv.tv_usec;
microsecond2time(time, ts);
printf("Received from [%s:%d]: %s\n", inet_ntoa(si_client.sin_addr), \
ntohs(si_client.sin_port), pkt.msg);
printf("Local time: %s\n", time);
if (pkt.sid != (last_sid + 1)) {
printf("Warning: missing sid, expected %llu but actually %llu\n", \
last_sid + 1, pkt.sid);
}
if (ts - pkt.ts > MAX_LATENCY) {
printf("Warning: the latency %llu exceeds the threshold %llu(us)\n", \
ts - pkt.ts, MAX_LATENCY);
}
last_sid = pkt.sid;
}
close(s);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment