DTS Application Library  0.2.3
Application library containing referenced objects and interfaces to common libraries
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Groups Pages
Socket Example (Echo Server/Client)

Details

Application flow

  • Check command line options if they correct daemonize.
  • If required create SSL sessions.
  • Create one server and 2 client sockets.
  • Bind the server socket.
  • Connect the clients to the server.
  • Start the server thread.
  • Start client threads.
  • Write the client name to the server via the client socket.
  • Echo back to the client and sleep the server thread for 1 second.
  • Sleep the main thread for 5 seconds allowing exit.

Annotation

See doxygen/examples/socket.c for annotated source code.

Code

#ifdef __WIN32
#include <winsock2.h>
#include <stdint.h>
#else
#include <fcntl.h>
#endif
#include <string.h>
#include <stdio.h>
#include <openssl/ssl.h>
#include <dtsapp.h>
void accept_func(struct fwsocket *sock, void *data) {
}
void server_func(struct fwsocket *sock, void *data) {
char buff[128];
union sockstruct addr;
if (socketread_d(sock, &buff, 128, &addr) > 0) {
socketwrite_d(sock, &buff, strlen(buff) + 1, &addr);
printf("[S] %s %i\n", buff, sock->sock);
sleep(1);
}
}
void client_func(struct fwsocket *sock, void *data) {
char buff[128];
if (socketread(sock, &buff, 128) > 0) {
socketwrite(sock, &buff, strlen(buff) + 1);
printf("[C] %s %i\n", buff, sock->sock);
}
}
void socktest(const char *ipaddr, int tcp, int ssl) {
struct fwsocket *serv, *client, *client2;
void *ssl_c = NULL, *ssl_s = NULL, *ssl_c2 = NULL;
char *buff = "client 1";
char *buff2 = "client 2";
int cnt;
if (ssl && tcp) {
ssl_s = sslv3_init("certs/cacert.pem", "certs/server-cert.pem", "certs/server-key.pem", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE);
ssl_c = sslv3_init("certs/cacert.pem", "certs/client-cert.pem", "certs/client-key.pem", SSL_VERIFY_NONE);
ssl_c2 = sslv3_init("certs/cacert.pem", "certs/client-cert.pem", "certs/client-key.pem", SSL_VERIFY_NONE);
} else if (ssl) {
ssl_s = dtlsv1_init("certs/cacert.pem", "certs/server-cert.pem", "certs/server-key.pem", SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE);
ssl_c = dtlsv1_init("certs/cacert.pem", "certs/client-cert.pem", "certs/client-key.pem", SSL_VERIFY_NONE);
ssl_c2 = dtlsv1_init("certs/cacert.pem", "certs/client-cert.pem", "certs/client-key.pem", SSL_VERIFY_NONE);
}
if (tcp) {
serv = tcpbind(ipaddr, "1111", ssl_s, 10);
client = tcpconnect(ipaddr, "1111", ssl_c);
client2 = tcpconnect(ipaddr, "1111", ssl_c2);
} else {
serv = udpbind(ipaddr, "1111", ssl_s);
client = udpconnect(ipaddr, "1111", ssl_c);
client2 = udpconnect(ipaddr, "1111", ssl_c2);
}
if (serv && client && client2) {
socketserver(serv, server_func, accept_func, NULL, NULL);
socketclient(client, NULL, client_func, NULL);
socketclient(client2, NULL, client_func, NULL);
socketwrite(client, buff, strlen(buff)+1);
socketwrite(client2, buff2, strlen(buff2)+1);
sleep(5);
} else {
printf("ERROR\n");
}
close_socket(client);
close_socket(client2);
close_socket(serv);
}
#ifndef __WIN32
void unixsocktest(const char *socket, int protocol) {
char *buff = "client 1";
char *buff2 = "client 2";
struct fwsocket *client, *client2, *server;
server = unixsocket_server(socket, protocol, S_IXUSR | S_IWGRP | S_IRGRP | S_IXGRP | S_IWOTH | S_IROTH | S_IXOTH, server_func, NULL);
sleep(1); /*wait for socket*/
client = unixsocket_client(socket, protocol, client_func, NULL);
client2 = unixsocket_client(socket, protocol, client_func, NULL);
socketwrite_d(client, buff, strlen(buff)+1, NULL);
socketwrite_d(client2, buff2, strlen(buff2)+1, NULL);
sleep(5);
close_socket(client);
close_socket(client2);
close_socket(server);
}
#endif
FRAMEWORK_MAIN("Socket Client/Server Echo (TCP/TLS/UDP/DTLS)", "Gregory Hinton Nietsky", "gregory@distrotech.co.za",
"http://www.distrotech.co.za", 2013, "/var/run/sockettest", FRAMEWORK_FLAG_DAEMONLOCK, NULL) {
if (argc < 3) {
#ifndef __WIN32
printf("Requires arguments %s [tcp|tls|udp|dtls|unix_d|unix_s] [ipaddr|socket]\n", argv[0]);
#else
printf("Requires arguments %s [tcp|tls|udp|dtls] ipaddr\n", argv[0]);
#endif
return (-1);
}
if (!strcmp(argv[1], "udp")) {
socktest(argv[2], 0, 0);
} else if (!strcmp(argv[1], "dtls")) {
socktest(argv[2], 0, 1);
} else if (!strcmp(argv[1], "tcp")) {
socktest(argv[2], 1, 0);
} else if (!strcmp(argv[1], "tls")) {
socktest(argv[2], 1, 1);
#ifndef __WIN32
} else if (!strcmp(argv[1], "unix_d")) {
unixsocktest(argv[2], SOCK_DGRAM);
} else if (!strcmp(argv[1], "unix_s")) {
unixsocktest(argv[2], SOCK_STREAM);
#endif
} else {
printf("Invalid Option\n");
}
}

Output

./socket tls ::1
Socket Client/Server Echo (TCP/TLS/UDP/DTLS)

Copyright (C) 2013 Gregory Hinton Nietsky <gregory@distrotech.co.za>

        http://www.distrotech.co.za

    This program comes with ABSOLUTELY NO WARRANTY
    This is free software, and you are welcome to redistribute it
    under certain conditions.

......./dtsapplib/private$ [S] client 1 19
[C] client 1 17
[S] client 2 20
[C] client 2 18
[S] client 1 19
[C] client 1 17
[S] client 2 20
[C] client 2 18
[S] client 1 19
[C] client 1 17
[S] client 2 20
[C] client 2 18
[S] client 1 19
[C] client 1 17
[S] client 2 20
[C] client 2 18
[S] client 1 19
[C] client 1 17
[S] client 2 20
[C] client 2 18
[S] client 1 19
[C] client 1 17
[S] client 2 20
[C] client 2 18