Socket and Networking Library using msgpack.org[C++11]

Overview

netLink

C++ 11 KISS principle networking library.

Build Status License

Features:

  • C++ 11
  • IPv4, IPv6
  • Protocols: TCP, UDP
  • Enable/Disable blocking mode
  • Join/Leave UDP-Multicast groups
  • UDP-IPv4-Broadcast
  • Operating Systems: Mac OS, Linux, Windows
  • MsgPack v5 support: http://msgpack.org so it can communicate with programs running in other programming languages
  • Optional: Upgrade std::string with UTF8 support
  • Socket can be used as std::streambuf
  • SocketManager calls various events for (dis)connecting, receiving data, connection requests and status changes
  • Event callbacks: onConnectRequest, onStatusChange, onReceiveRaw, onReceiveMsgPack

Example Code:

UDP, TCP

Wiki:

Doxygen online documentation

MsgPack tutorial

Comments
  • socketmanager and ONE TcpServer socket

    socketmanager and ONE TcpServer socket

    Hi again!

    This code produce an exception in Windows (Visual Studio 2015) in socketManager.listen(5.0);

    is it normal?? :-O

    DJuego

    
    
    int main(int argc, char** argv) {
    	//#ifdef WINVER
    	netLink::init();
    	//#endif
    
    	netLink::SocketManager socketManager;
    	std::shared_ptr<netLink::Socket> socket = socketManager.newSocket();
    	try
    	{
    		socket->initAsTcpServer("0.0.0.0", 3015);
    	}
    	catch (netLink::Exception exc)
    	{
    		std::cout << "Address is already in use" << std::endl;
    		return 1;
    	}
    	socket->setBlockingMode(false);
    
    	socketManager.onReceiveRaw = [](netLink::SocketManager *manager, std::shared_ptr< netLink::Socket > socket)
    		{
    
    			std::cout << "Receiving..." << std::endl;			
    		};
    
    
    		while (true)
    			socketManager.listen(5.0);
    
    
    	return 0;
    }
    
    
    bug 
    opened by DJuego 13
  • Sending Message packet

    Sending Message packet

    Hi, @Lichtso

    i found difficulties sending data over another ip using TCP server. Likely in your code just receiving method define. What about sending data method to source. if you can guide me.

    your code is

    socket->hostRemote = (socket->getIPVersion() == netLink::Socket::IPv4) ? "224.0.0.100" : "FF02:0001::"; socket->portRemote = socket->portLocal;

    // Join the multicast group to receive messages from the given address
    socket->setMulticastGroup(socket->hostRemote, true);
    
    // Prepare a MsgPack encoded message
    netLink::MsgPackSocket& msgPackSocket = *static_cast<netLink::MsgPackSocket*>(socket.get());
    msgPackSocket << MsgPack::Factory("Hello World!");
    //msgPackSocket << MsgPack__Factory(ArrayHeader(2));
    msgPackSocket << MsgPack__Factory(ArrayHeader(3));
    msgPackSocket << MsgPack__Factory(MapHeader(2));
    msgPackSocket << MsgPack::Factory("Boolean");
    msgPackSocket << MsgPack::Factory(true);
    msgPackSocket << MsgPack::Factory("Number");
    msgPackSocket << MsgPack::Factory(2487.348);
    msgPackSocket << MsgPack__Factory(ArrayHeader(0));
    msgPackSocket << MsgPack::Factory();
    

    this source code for UDP which i show in your Example folder. i get that idea about socket manager but now i am trying to send data to another pc using tcp server and i am new in this socket field. If you can help me.

    instead of multicast group just sending to only one destination using TCP Server id. if you know how...

    thank you..
    Bruce Washington

    question 
    opened by BruceWashington13 11
  • SocketManager::listen return an exit status code...

    SocketManager::listen return an exit status code...

    Hi Lichtso. ;-)

    I wanted to ask you about the possibility that SocketManager::listed return a exit status code, or at least, a boolean with true or false if the timeout has expired or not.

    I thought about this proposal while I tried to solve the next problem;


    I am working with the LEGO MindStorms EV3 bricks and the official firmware. In this case I only 'control' one side of the connection [Would this reason be the cause of the problem?]. I am using raw data.

    In this context I have detected an anomaly with "SocketManager::listen". The socket is a TCP_CLIENT.

    The "listen" does not "wait", and it does not invoke an event ( onReceiveRaw, onStatusChange) Neither throw an exception away. I am without clues. :-(

    In order to get more details perhaps i need debug the netlink library for my very specific use case. :-/ Perhaps later on I make it. However i can not use breakpoints why the problem disappears.

    The "workaround" most simple i have found for my problem is to add an active wait BEFORE the SocketManager::listen

    std::size_t recibirTimeOut(std::shared_ptr<netLink::Socket> psocket, char *m_recepcion, const std::size_t tamanomaximorecepcion)
    {
        std::size_t recibidotcp = 0;
        netLink::SocketManager socketManager;
        socketManager.sockets.insert(psocket); //<-is this legal? it works but...
    
        socketManager.onReceiveRaw = [m_recepcion, &recibidotcp, tamanomaximorecepcion](netLink::SocketManager* manager, std::shared_ptr<netLink::Socket> socket)
        {
            recibidotcp = socket->sgetn(m_recepcion, tamanomaximorecepcion);
        };
    
    //A -one second- active wait ... Why?
        std::chrono::high_resolution_clock::time_point end, start;
        std::chrono::seconds ms;
        start = std::chrono::high_resolution_clock::now();
        do
        {
            end = std::chrono::high_resolution_clock::now();
            ms = std::chrono::duration_cast<std::chrono::seconds>(end - start);
        }
        while (ms.count() < 1);
    //end of active wait
    
       socketManager.listen(5.0);
       return recibidotcp;
    }
    
    
    bug 
    opened by DJuego 11
  • initAsTcpServer(

    initAsTcpServer("*", port);

    Sorry, @Lichtso . Again me.

    I am using Windows 10 x64 with Visual Studio 2015.

    Briefly;

    initAsTcpServer("0.0.0.0", port); works but initAsTcpServer("*", port); does not work (IPv6 is selected automatically) In fact, initAsTcpServer("::0", 3823); does not work

    Sample Code:

    #include <iostream>
    #include <netLink/netLink.h>
    int main(int argc, char** argv) 
    {
    //#ifdef WINVER
    	netLink::init();
    //#endif
    	netLink::SocketManager socketManager;
    	std::shared_ptr<netLink::Socket> socket = socketManager.newSocket();
    	try 
    	{		
    		//socket->initAsTcpServer("0.0.0.0", 3823);
    		socket->initAsTcpServer("*", 3823);
    	}
    	catch (netLink::Exception exc)
    	{
    		std::cout << "Exception: "<< exc.code << std::endl; //I get ERROR_SET_SOCK_OPT(3)
    	}
    }
    

    The exception occurs in Socket::initSocket (Socket.cpp)

    if(ipVersion == IPv6) {
                flag = 0;
                if(setsockopt(handle, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) == -1) {
                    disconnect();
                    throw Exception(Exception::ERROR_SET_SOCK_OPT);
                }
    
    bug 
    opened by DJuego 9
  • Windows 10 Support

    Windows 10 Support

    Hello Lichtso! I have come back! :-)

    I simply wanted to report to you that netlink seems not to get compiled with Microsoft Visual Studio 14.0.

    I have attached a full log for:

    cmake -G 'NMake Makefiles' -D CMAKE_BUILD_TYPE=Debug -D CMAKE_INSTALL_PREFIX=$DIRECTORIO_LOCAL -D DOXYGEN_EXECUTABLE=$ARCHIVO_DOXYGEN -D DOXYGEN_DOT_EXECUTABLE=$ARCHIVO_DOT  ../.. 
    nmake   
    

    and

    cmake -G 'NMake Makefiles' -D CMAKE_BUILD_TYPE=Release -D CMAKE_INSTALL_PREFIX=$DIRECTORIO_LOCAL -D DOXYGEN_EXECUTABLE=$ARCHIVO_DOXYGEN -D DOXYGEN_DOT_EXECUTABLE=$ARCHIVO_DOT  ../..       
    nmake
    

    However, it builds like a charm in MinGW 5.3.0

    P.S: I have the same problem with: cmake -G 'Visual Studio 14 2015'

    output log netlink

    bug 
    opened by DJuego 9
  • Building in MinGW 4.9.2

    Building in MinGW 4.9.2

    I have built netLink directly in Visual Studio 2013 and Sourcery_CodeBench_Lite_for_ARM_GNU_Linux without problems. The examples works flawlessly. ;-) However I have troubles with Mingw-builds (gcc 4.9.2)

    The first problem was related with the IPV6 support: Socket.cpp:39:77: error: 'inet_ntop' was not declared in this scope I resolved it with #define _WIN32_WINNT 0x0602 in Socket.cpp.

    The current problem says:

    g++.exe -Wall -std=c++11 -DWIN32 -g -I....\inc\netLink\include -c P:\Mis-Proyectos\Cross-compilados\EV3\Control_PC_EV3\inc\netLink\src\Utf8.cpp -o obj\Debug\inc\netLink\src\Utf8.o In file included from P:\Mis-Proyectos\Cross-compilados\EV3\Control_PC_EV3\inc\netLink\src\Utf8.cpp:16:0: ....\inc\netLink\include/Utf8.h: In function 'size_t utf8::byteSize(iterator)': ....\inc\netLink\include/Utf8.h:22:44: error: there are no arguments to '__lzcnt' that depend on a template parameter, so a declaration of '__lzcnt' must be available [-fpermissive] #define countLeadingOneBits(x) __lzcnt(~(x)) ^ ....\inc\netLink\include/Utf8.h:142:7: note: in expansion of macro 'countLeadingOneBits' s = countLeadingOneBits(c << 24); ^ ....\inc\netLink\include/Utf8.h:22:44: note: (if you use '-fpermissive', G++ will accept your code, but allowing the use of an undeclared name is deprecated) #define countLeadingOneBits(x) __lzcnt(~(x))

    [...]

    bug 
    opened by DJuego 9
  • getType()

    getType()

    I am struggling with serialization and related content. :-(. In the next example:

    int main()
    {
    
    //STAGE 1
        std::vector<std::unique_ptr<MsgPack::Element>> arrayWith3Elements;
        arrayWith3Elements.push_back(MsgPack::Factory(static_cast<uint64_t>(1)));
        arrayWith3Elements.push_back(MsgPack::Factory(static_cast<int64_t>(177)));
        arrayWith3Elements.push_back(MsgPack::Factory(static_cast<float>(-64.0f)));
        arrayWith3Elements.push_back(MsgPack::Factory(static_cast<double>(-64.0f)));
    
        std::unique_ptr<MsgPack::Element> p = MsgPack__Factory(Array(std::move(arrayWith3Elements)));
    
    //STAGE 2
        auto array= dynamic_cast<MsgPack::Array*>(p.get());
        if (array)
        {
            auto contenedor = array->getContainer();
            for (auto const &elemento : (*contenedor))
            {
    
                MsgPack::Type type = elemento->getType();
                switch (type)
                {
                case MsgPack::UINT_64:
                {
                    std::cout << "UINT64" << std::endl;
                    break;
                }
                case MsgPack::INT_64:
                {
                    std::cout << "INT64" << std::endl;
                    break;
                }
                case MsgPack::FLOAT_32:
                {
                    std::cout << "FLOAT32" << std::endl;
                    break;
                }
                case MsgPack::FLOAT_64:
                {
                    std::cout << "FLOAT64" << std::endl;
                    break;
                }
                default:
                    std::cout << "UNKNOWN" << std::endl;
                    break;
    
                }
            }
        }
        std::cin.get();
        return 0;
    }
    

    The expected output was:

    UINT64
    INT64
    FLOAT32
    FLOAT64
    
    

    The output was:

    UNKNOWN
    UNKNOWN
    FLOAT32
    FLOAT64
    

    Why "UNKNOWN"?

    :-/

    enhancement question 
    opened by DJuego 8
  • Failed to unpack msgpack data in Windows for large strings

    Failed to unpack msgpack data in Windows for large strings

    The foo.gz file is generated by the following python script:

    import msgpack
    with open('foo.gz', 'rb') as f:
        f.write(msgpack.packb(['a'*i for i in xrange(0, 100000, 20000)]))
    

    When deserializing in windows using the following code, it failed to parse all strings.

        std::ifstream fileStream("foo.gz", std::ios::in | std::ios::binary);
        MsgPack::Deserializer deserializer(fileStream.rdbuf());
    	deserializer.deserialize([](std::unique_ptr<MsgPack::Element> parsed) {
    		std::cout << *parsed << std::endl;
    		exit(0);
    		return false;
    	}, true);
    

    the output is:

    ["", "aaaa...", 97, 97, 97]
    

    foo.gz

    bug 
    opened by ywx217 7
  • Runs only on Unix

    Runs only on Unix

    You should probably state that this library only compiles on Unix systems, as the following block in Core.h:

    #include <arpa/inet.h> #include <sys/fcntl.h> #include <netdb.h> #include <sys/ioctl.h> #include <unistd.h>

    are not available on Windows. I get errors for each line saying "Cannot open source file ____".

    opened by d223chen 6
  • Server sockets default to IPv6 only on windows

    Server sockets default to IPv6 only on windows

    Hi,

    I compiled the tcp example, and played around with it. I noticed that I could not connect using IPv4 addresses (it would connect to "localhost", "::1" but not "127.0.0.1") . I did a bit of research and the problem seems to be that on windows, the "IPV6_V6ONLY" socket option defaults to 1 according to http://stackoverflow.com/questions/1618240/how-to-support-both-ipv4-and-ipv6-connections.

    I confirmed that by executing the following snippet within "initSocket" in Socket.cpp:

    DWORD ipv6only = 0;
    if(setsockopt(handle, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&ipv6only, sizeof(ipv6only)) == -1) {
        disconnect();
        throw Exception(Exception::ERROR_SET_SOCK_OPT);
    }
    

    Using that fixed the issue and I could connect using both "::1" and "127.0.0.1". However I'm not really sure where the snippet belongs. I put it right after the other "setsockopt"-calls, but that seems wrong, as it would also be set for UDP or IPv4 clients.

    Best regards

    enhancement 
    opened by powertomato 6
  • Buffer Overflow problems

    Buffer Overflow problems

    I've been investigating a memory issue in our application and found it was a buffer overflow originating from a MsgPack-socket in netlink.

    I've created a gist to help illustrate it. It consists of the source code, that replicates the problem for me and the trace output of dr. memory: https://gist.github.com/powertomato/341a32754b1c8702a98c8f5f15534a9e

    What the code does is sets the buffer-lengths to 2, then replies to the connecting client with a map in an array: (in JSON for readability) [{"fo":0}] which results in a segfault or "UNADDRESSABLE ACCESS" as dr. memory detects it. What's odd: sending a long string, doesn't produce the same result. If buffer length needs to be longer than the maximum encoded message, I'd expect it to fail in a more graceful manner.

    So far I've only been able to replicate it when writing to the socket: if I send the same array with netcat to the test app: echo -e -n '\x91\x81\xa2fo\x00' | nc localhost 9998, it gets parsed correctly, no segfault or dr. memory error.

    I'm using MSYS2 on windows, with gcc v7.3 and binutils v2.30

    bug 
    opened by powertomato 5
  • Conflict with WINVER on Windows 10 x64

    Conflict with WINVER on Windows 10 x64

    Hi @Lichtso! It's been a long time! I still use your library! Thanks for this!! I am working in Microsoft Visual Studio 2019 environment. WINVER does not seem to work. I need it for conditional compilation:

    #ifdef WINVER
    #include <SDKDDKVer.h>
    #include <Ws2tcpip.h>
    #pragma comment(lib, "Ws2_32.lib")
    #undef min
    #undef max
    #else
    

    I get:

     #error:  WINVER setting conflicts with _WIN32_WINNT setting
    

    DJuego

    opened by DJuego 3
  • multicastgroup msg can only be received/consumed by one client?

    multicastgroup msg can only be received/consumed by one client?

    #include <iostream>
    #include <thread>
    #include "../include/netLink.h"
    
    int main(int argc, char** argv) {
    
    #ifdef WINVER
    	netLink::init();
    #endif
    
    	netLink::SocketManager socketManager;
    
    	socketManager.onReceiveMsgPack = [](netLink::SocketManager* manager, std::shared_ptr<netLink::Socket> socket, std::unique_ptr<MsgPack::Element> element) {		
    		auto& str = static_cast<MsgPack::String&>(*element.get());
    		auto val = atoi(str.getData());
    		std::cout << socket->hostRemote << " val:" << val << std::endl;
    	};
    
    	std::shared_ptr<netLink::Socket> socket = socketManager.newMsgPackSocket();
    
    	try {
    		socket->initAsUdpPeer("*", 3824);
    	}
    	catch (netLink::Exception exc) {
    		std::cout << "Address is already in use" << std::endl;
    		return 1;
    	}
    	
    	socket->hostRemote = (socket->getIPVersion() == netLink::Socket::IPv4) ? "224.0.0.100" : "FF02:0001::";
    	socket->portRemote = socket->portLocal;
    
    	socket->setMulticastGroup(socket->hostRemote, true);
    
    	std::thread t1([&](){
    		while (true){
    			socketManager.listen();
    		}
    	});
    
    	netLink::MsgPackSocket& msgPackSocket = *static_cast<netLink::MsgPackSocket*>(socket.get());
    
    	for (int i = 0; i < 100; ++i){			
    		char msg[256] = {0};
    		sprintf(msg, "%02d", i);
    		msgPackSocket << MsgPack::Factory(msg);
    		std::this_thread::sleep_for(std::chrono::seconds(1));
    	}
    
    	t1.join();
    
            return 0;
    }
    
    opened by godsonhyl 1
  • Fix Socket::sync if a client is disconnected

    Fix Socket::sync if a client is disconnected

    If a client is disconnected during the transfer progress, socket status will be BUSY. Socket::sync will not be able to write any data and should return EOF instead.

    opened by lishuren 3
  • Support for Data Compression

    Support for Data Compression

    Notes:

    1. Maybe something like: https://github.com/Cyan4973/lz4 (as proposed by DJuego)
    2. Should be an optional dependency, extending the functionality of netLink when installed
    3. Could be for the entire data stream, message based or element based (Using an MsgPack "Extension type")
    enhancement 
    opened by Lichtso 0
Owner
Alexander Meißner
Freelancer, Working on my project @Symatem in my free time
Alexander Meißner
Portable, single-file, protocol-agnostic TCP and UDP socket wrapper, primarily for game networking

Documentation This is a header-only library, as such most of its functional documentation is contained within the "header section" of the source code

null 64 Dec 3, 2022
Packio - An asynchronous msgpack-RPC and JSON-RPC library built on top of Boost.Asio.

Header-only | JSON-RPC | msgpack-RPC | asio | coroutines This library requires C++17 and is designed as an extension to boost.asio. It will let you bu

Quentin Chateau 58 Dec 26, 2022
Simple server and client using python socket and declarative programming

Socket-programming Simple server and client using python socket and declarative programming How to use? open cmd and navigate to the location of the s

MAINAK CHAUDHURI 24 Dec 17, 2022
Provide translation, currency conversion, and voting services. First using telnet you create a connection to a TCP socket, then the server connects to 3 UDP sockets hosted on other servers to do tasks.

to run micro servers g++ translator.cpp -o translator ./translator <port 1> g++ voting.cpp -o voting ./voting <port 2> g++ currency_converter.cpp -o c

Jacob Artuso 1 Oct 29, 2021
Faster termux-am implementation that connects to a receiver in termux-app using a unix socket

termux-am-socket This is a small program for sending commands to the Termux:API app, thereby allowing terminal programs to use the Android API. The pr

Termux 26 Dec 21, 2022
The program shows how bluetooth devices are connected, without using socket programming

The program shows how bluetooth devices are connected, without using socket programming, it shows how files are shared using principles of OOP

SAKSHI JAIN 2 Oct 5, 2022
requests-like networking library using boost for C++

cq == C++ Requests cq == C++ Requests is a "Python Requests"-like C++ header-only library for sending HTTP requests. The library is inspired a lot by

null 11 Dec 15, 2021
Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution

CppServer Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and

Ivan Shynkarenka 958 Jan 3, 2023
A single-header socket library for both Linux and Windows

COMS What is COMS? COMS is a single-header library designed to be simple to use. It supports TCP and UDP, Server and Client. Available for Windows and

null 5 Dec 23, 2021
Mongoose Embedded Web Server Library - a multi-protocol embedded networking library with TCP/UDP, HTTP, WebSocket, MQTT built-in protocols, async DNS resolver, and non-blocking API.

Mongoose - Embedded Web Server / Embedded Networking Library Mongoose is a networking library for C/C++. It implements event-driven non-blocking APIs

Cesanta Software 9k Jan 1, 2023
Modern C++ socket library.

sockpp Simple, modern, C++ socket library. This is a fairly low-level C++ wrapper around the Berkeley sockets library using socket, acceptor, and conn

Frank Pagliughi 532 Dec 28, 2022
Lightweight, header-only, Boost-based socket pool library

Stream-client This is a lightweight, header-only, Boost-based library providing client-side network primitives to easily organize and implement data t

Tinkoff.ru 12 Aug 5, 2022
Minimalistic socket library inspired by Asio/Boost Asio, implemented in 1 single header file

cz-spas czspas (Small Portable Asynchronous Sockets) is minimalistic socket library inspired by Asio/Boost Asio, implemented in 1 single header file.

Rui Figueira 26 Nov 30, 2022
Asynchronous, Header-only C++ HTTP-over-(TCP|UNIX Socket|STDIO) Library

CXXHTTP A C++ library implementing an asynchronous HTTP server and client. To clone this library, make sure you also clone the submodules. The --recur

null 25 Mar 19, 2021
The C++ Network Library Project -- cross-platform, standards compliant networking library.

C++ Network Library Modern C++ network programming libraries. Join us on Slack: http://slack.cpp-netlib.org/ Subscribe to the mailing list: https://gr

C++ Network Library 1.9k Dec 27, 2022
Boost.org signals2 module

Signals2, part of collection of the Boost C++ Libraries, is an implementation of a managed signals and slots system. License Distributed under the Boo

Boost.org 52 Dec 1, 2022
Boost.org property_tree module

Maintainer This library is currently maintained by Richard Hodges with generous support from the C++ Alliance. Build Status Branch Status develop mast

Boost.org 36 Dec 6, 2022
Small and fast cross-platform networking library, with support for messaging, IPv6, HTTP, SSL and WebSocket.

frnetlib Frnetlib, is a cross-platform, small and fast networking library written in C++. There are no library dependencies (unless you want to use SS

Fred Nicolson 23 Nov 25, 2022
As a Teaching Assistant, this is a sample project about socket programming for my teaching in a capstone course in NTUST(National Taiwan University of Science and Technology)

socket-programming As a Teaching Assistant, this is a sample project about socket programming for my teaching in a capstone course in NTUST(National T

Chang Wei 2 Oct 26, 2021