Need help with kissnet?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

Ybalrid
124 Stars 28 Forks MIT License 183 Commits 6 Opened issues

Description

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

Services available

!
?

Need anything else?

Contributors list

# 137,785
Shell
XML
linker
cpluspl...
108 commits
# 56,926
Twitch
perisco...
fortran
pypi
22 commits
# 4,884
xbmc
Linux
media-p...
macOS
7 commits
# 619,378
C++
Python
Shell
2 commits
# 370,575
C++
Shell
C
irc-cli...
2 commits
# 201,555
raylib
Raspber...
C
videoga...
1 commit

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 
#include 
#include 

#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&lt;4096&gt; 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 &lt;&lt; "bytes available to read : " &lt;&lt; a_socket.bytes_available() &lt;&lt; '\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 &lt; 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 &lt;&lt; reinterpret_cast<const char>(static_buffer.data()) &lt;&lt; '\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&lt;4096&gt; 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 &lt;&lt; "bytes available to read : " &lt;&lt; a_socket.bytes_available() &lt;&lt; '\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 &lt; 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 &lt;&lt; reinterpret_cast<const char>(static_buffer.data()) &lt;&lt; '\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&lt;16&gt; buff;

    //Build data to send (flat array of bytes
    for(unsigned char i = 0; i &lt; 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&lt;16&gt; recv_buff;

    //Actually print bytes_available
    std::cout &lt;&lt; "avaliable in UDP socket : " &lt;&lt; b_socket.bytes_available() &lt;&lt; " 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 &lt;&lt; "Received: ";

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

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

//So long, and thanks for all the fish
return 0;

</kissnet.hpp>

  • TCP listener
#include 
#include 

namespace kn = kissnet;

int main() { //setup socket kn::socket<: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&lt;1024&gt; buff;
const auto [size, status] = client.recv(buff);

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

return 0;

}

</:protocol::tcp></kissnet.hpp>

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.