• Stars
    star
    229
  • Rank 173,556 (Top 4 %)
  • Language
    C++
  • License
    MIT License
  • Created about 6 years ago
  • Updated about 2 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Keep It Simple Stupid NETwork - C++17 wrapping of your OS's native socket API

kissnet

Build Status Build status ci Total alerts Language grade: C/C++ License: MIT

Keep It Simple Stupid NETwork.

The thought that led me to write this thing are better explained in this article

A lightweight, header only, crossplatform C++17 socket library.

Wrap all annoying C api calls to the OS inside a socket template class

Features:

  • Stupidly simple
  • TCP socket
  • TCP SSL socket
  • UDP socket
  • ipv4 and ipv6 support
  • Error reporting with and without exceptions
    • You can deactivate exception support. If you do so, library will by default log to stderr (without iostream), and abort program
    • You can provide a custom error handling callback, and you can deactivate the automatic abort by the error handler
  • Communicate with buffers of C++17 std::byte
  • Manage required library (e.g. WinSock2) initialization and cleanup for you RAII style. Network is de-initialized when last socket object goes out of scope
  • Use familiar names for socket operations as methods: send, recv, connect, bind, listen, accept...

Supported platforms:

kissnet was desinged to be a slingle API for using low level tcp and udp sockets on any platform where you can run a modern C++ compiler. Kissnet currently supports

  • Windows (via the WSA/WinSock2 libraries)
  • Linux
  • FreeBSD
  • Haiku OS (needs to be linked to libnetwork. either use target_link_libraries(target network) with cmake, or -lnetwork in yoru compile command), networking will use the posix headers shiped with the OS, not the BeOS-like C++ network kit.

kissnet should probably work "as is" on other UNIX platform.

Short docs

kissnet.hpp can be copied to your project's directory, or if you wish it can be installed and used from CMake as interface target kissnet:

cmake -B build
cmake --install build

Examples

Volontary contrived examples showing how the library looks like:

You can take a look a some of the programs in the examples directory.

  • Basic client usage, tcp connect and read, udp send, udp read
#include <iostream>
#include <thread>
#include <chrono>

#include <kissnet.hpp>
using namespace std::chrono_literals;
namespace kn = kissnet;

int main()
{

    /* No need to initializate SSL because its initializated at start of program if KISSNET_USE_OPENSSL is used. */

	{
		//Create a kissnet tcp over ssl ipv4 socket
		kn::tcp_ssl_socket a_socket(kn::endpoint("cpz.github.io:443"));
		a_socket.connect();

		//Create a "GET /" HTTP request, and send that packet into the socket
		auto get_index_request = std::string{ "GET / HTTP/1.1\r\nHost: cpz.github.io\r\n\r\n" };

		//Send request
		a_socket.send(reinterpret_cast<const std::byte*>(get_index_request.c_str()), get_index_request.size());

		//Receive data into a buffer
		kn::buffer<4096> static_buffer;

		//Useless wait, just to show how long the response was
		std::this_thread::sleep_for(1s);

		//Print how much data our OS has for us
		std::cout << "bytes available to read : " << a_socket.bytes_available() << '\n';

		//Get the data, and the lengh of data
		const auto [data_size, status_code] = a_socket.recv(static_buffer);

		//To print it as a good old C string, add a null terminator
		if(data_size < static_buffer.size())
			static_buffer[data_size] = std::byte{ '\0' };

		//Print the raw data as text into the terminal (should display html/css code here)
		std::cout << reinterpret_cast<const char*>(static_buffer.data()) << '\n';
	}

	/* Nothing need to do for OpenSSL uninitialization because our class will do everything by himself. */

	/*No more socket here, this will actually close WSA on Windows*/

	{
		//Create a kissnet tcp ipv4 socket
		kn::tcp_socket a_socket(kn::endpoint("avalon.ybalrid.info:80"));
		a_socket.connect();

		//Create a "GET /" HTTP request, and send that packet into the socket
		auto get_index_request = std::string{ "GET / HTTP/1.1\r\nHost: avalon.ybalird.info\r\n\r\n" };

		//Send request
		a_socket.send(reinterpret_cast<const std::byte*>(get_index_request.c_str()), get_index_request.size());

		//Receive data into a buffer
		kn::buffer<4096> static_buffer;

		//Useless wait, just to show how long the response was
		std::this_thread::sleep_for(1s);

		//Print how much data our OS has for us
		std::cout << "bytes available to read : " << a_socket.bytes_available() << '\n';

		//Get the data, and the lengh of data
		const auto [data_size, status_code] = a_socket.recv(static_buffer);

		//To print it as a good old C string, add a null terminator
		if(data_size < static_buffer.size())
			static_buffer[data_size] = std::byte{ '\0' };

		//Print the raw data as text into the terminal (should display html/css code here)
		std::cout << reinterpret_cast<const char*>(static_buffer.data()) << '\n';
	}

	/*No more socket here, this will actually close WSA on Windows*/

	{
		//Socket used to send, the "endpoint" is the destination of the data
		kn::udp_socket a_socket(kn::endpoint("127.0.0.1", 6666));

		//Socket used to receive, the "endpoint" is where to listen to data
		kn::udp_socket b_socket(kn::endpoint("0.0.0.0", 6666));
		b_socket.bind();

		//Byte buffer
		kn::buffer<16> buff;

		//Build data to send (flat array of bytes
		for(unsigned char i = 0; i < 16; i++)
			buff[i] = std::byte{ i };

		//Send data
		a_socket.send(buff.data(), 16);

		//Same deal as above
		std::this_thread::sleep_for(1s);

		//We do know, for the sake of the example, that there are 16 bytes to get from the network
		kn::buffer<16> recv_buff;

		//Actually print bytes_available
		std::cout << "avaliable in UDP socket : " << b_socket.bytes_available() << " bytes\n";

		//You receive in the same way
		auto [received_bytes, status] = b_socket.recv(recv_buff);
		const auto from = b_socket.get_recv_endpoint();

		//Print the data
		std::cout << "Received: ";

		for(unsigned char i = 0; i < 16; i++)
		{
			std::cout << std::hex << std::to_integer<int>(recv_buff[i]) << std::dec << ' ';
		}

		//Print who send the data
		std::cout << "From: " << from.address << ' ' << from.port << '\n';
	}

	//So long, and thanks for all the fish
	return 0;
  • TCP listener
#include <kissnet.hpp>
#include <iostream>

namespace kn = kissnet;

int main()
{
	//setup socket
	kn::socket<kissnet::protocol::tcp> server(kn::endpoint("0.0.0.0:8080"));
	server.bind();
	server.listen();

	//Wait for one co
	auto client = server.accept();

	//Read once in a 1k buffer
	kn::buffer<1024> buff;
	const auto [size, status] = client.recv(buff);

	//Add null terminator, and print as string
	if(size < buff.size()) buff[size] = std::byte{ 0 };
	std::cout << reinterpret_cast<const char*>(buff.data()) << '\n';

	return 0;
}

More Repositories

1

Ogre_glTF

glTF 2.0 asset loader plugin for Ogre 2.1
C++
48
star
2

Annwvyn

Annwvyn C++ Open Source designed-for-VR game engine and application developement framework
C++
40
star
3

cmake-cpp-nasm

Assembly
35
star
4

BtOgre2

Compatible with current v2-1/v2-2 OGRE Branch! Thin communication layer between Bullet Physics and Ogre 2.x with a debug drawer. Forked from BtOgre.
C++
22
star
5

Qt5Ogre21

Qt 5 integration for Ogre 2.1
C++
21
star
6

OpenXR-Runtime-Manager

A tool that permit you to see and switch the currently active OpenXR runtime
C#
17
star
7

OpenXR-API-Layer-Template

A CMake based template repository to create OpenXR layers in C++
C++
8
star
8

plugin

A simple and safe C++ plugin system as a header-only library
C++
6
star
9

systemd-numlockontty

Shell
5
star
10

gl_framework

simple opengl framework from polutropon games
C++
5
star
11

Ogre21_VR

Demo project of using Ogre 2.1 compositor to render to VR hardware, using the Oculus SDK and/or the OpenVR API
C++
3
star
12

OpenXR-info

C++
2
star
13

ST_VL6180X

Official St Microelectronics API for VL6180X proximity and ambient light sensor. Plan to add build system and support for raspberry pi I2C.
C
2
star
14

mma8451_pi

C library to use a MMA8451 accelerometer on a raspberry pi
C
2
star
15

ogre-oculus-opengl

This is a repo for testing SDK 0.7 with ogre. This is totally obsolette.
C++
2
star
16

PODFirmware

Omnidirectional treadmill for VR - ESIEA PST project
C++
1
star
17

zipcomment

CLI tool that allow writing an arbitrary string in the End Of Central Directory
C++
1
star
18

OgreOculusRenderer

For using the Oculus DK1 with Ogre on Linux with the OculusSDK 0.3.x patched from here : https://github.com/Ybalrid/OculusSDK
C++
1
star
19

dx11-share-test

Useless program that just create a shared texture, and open it across two Direct3d 11 devices
C++
1
star
20

yaz80c

yet another z80 computer
Assembly
1
star
21

SSVK

Super Simple Virtual Keypress : A Windows/Linux solution to generate system-wide keyboard events.
C++
1
star
22

zipconcat

CLI Tool to append a zip archive to an executable (or anything really...)
C++
1
star
23

stk11xx-patched

Linux Kernel module for syntek USB webcam - patched to build on mordern kernels
C
1
star
24

ChaTTY

A chat for chatty people that runs on your terminal over a LAN
C++
1
star
25

AnnwvynDeps

Repository to construct the Annwvyn dependency package
C++
1
star
26

Voron2-UNIT-01-KlipperConfig

CSS
1
star
27

chaiscript-glm

OpenGL Mathematics bindings for ChaiScript
C++
1
star
28

OgreManualMinimalApplication

Dรฉpot vide d'exemple avec un fichier c++ et un makefile qui compille une aplication "de base" lancรฉe avec Ogre sous Ubnutu 14.04
C++
1
star
29

virtual-air-hockey

Repository for PST4 project "air hockey with Oculus Rift and Novint Falcon"
C++
1
star