lichtso / netlink Goto Github PK
View Code? Open in Web Editor NEWSocket and Networking Library using msgpack.org[C++11]
License: GNU General Public License v3.0
Socket and Networking Library using msgpack.org[C++11]
License: GNU General Public License v3.0
Again me, Lichtso! Hi! :-D
During these months I have been with other projects but I am back. 👍
I have several problems with this code (i have isolated the problems from my super-project. :-D):
[Link to pastecode]
I feel the code is so big but at least it's complete and it can be run.
I am working in Windows 10 x64 with Visual Studio 2015.
a) The Receiver only receive a packet! :-((( However if the Receiver and The Sender run in the same computer the program works.
b) In The Sender, the socket receives its own packet (I suspect this has to do with the cause of the problem)
c) This program works perfectly if the line socketManager.listen(5.0); is commented (in The Sender).
Questions:
Q1: The socket receives its own packet. Can this behavior be avoided?
Q2: Does this mean that it is not possible to listen from a socket that is broadcasting ?
[PD:
**Really now i understand perfectly that the answers are:
A1: No. The behaviour is correct!
A2: No. This mean you should'nt do it.
:-D
**
]
#include <iostream>
#include <chrono>
#include <string>
#include <netLink/netLink.h>
char data[128];
void wait(int milliseconds)
{
std::chrono::high_resolution_clock::time_point end, start;
std::chrono::milliseconds ms;
start = std::chrono::high_resolution_clock::now();
do
{
end = std::chrono::high_resolution_clock::now();
ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
} while (ms.count() < milliseconds);
}
int main(int argc, char** argv) {
//#ifdef WINVER
netLink::init();
//#endif
netLink::SocketManager socketManager;
std::shared_ptr<netLink::Socket> socket = socketManager.newSocket();
try
{
socket->initAsUdpPeer("0.0.0.0", 3015);
}
catch (netLink::Exception exc)
{
std::cout << "Address is already in use" << std::endl;
return 1;
}
socket->setBlockingMode(false);
if (argc > 1)
{
std::cout << "The Receiver" << std::endl;
socketManager.onReceiveRaw = [](netLink::SocketManager *manager, std::shared_ptr< netLink::Socket > socket)
{
std::cout << "Receiving..." << std::endl;
std::size_t size = socket->sgetn(data, 128);
//std::size_t size = socket->receive(data, 128);
if (size > 0)
{
std::cout << "Incoming data: " << data << std::endl;
}
else
{
std::cout << "NO DATA???" << std::endl;
}
};
while (true)
socketManager.listen(5.0);
}
else
{
std::cout << "The Sender" << std::endl;
socket->setBroadcast(true);
socket->hostRemote = "255.255.255.255";
socket->portRemote = socket->portLocal;
char* data = "My data\0";
while (true)
{
wait(1000);
std::cout << "Listening..." << std::endl;
socketManager.listen(5.0); //THIS LINE IS PROBLEMATIC. THE PROGRAM DOES NOT WORK!!! :-(
std::cout << "Sending..." << std::endl;
std::streamsize size = socket->send(data, 128);
}
}
return 0;
}
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"?
:-/
I am using Visual Studio 2017 with Microsoft Visual C++ (MSVC++) compiler.
How do I build and create the libraries for this repo?
Right now all I have is the headers and source code. I have tried loading the headers and source code into a project and building with the /DLL option. The compiler tells me "entry point must be defined".
I suggest different "names" for lib and release lib files. For example;
For example;
Debug:
netLink-d.dll
netLink-d.lib
Release:
netLink.dll
netLink.lib
In this way the Lib files could share directory. Also it avoids "accidents".
Perhaps with:
set_target_properties( netLink PROPERTIES DEBUG_POSTFIX -d )
Hi! First; My sincere appreciation, Lichtso. During the last months I have worked frequently with your library, successfully. I have a few questions and stories for you. :-)
However now i want to declare a building problem with netLink in "Visual Studio 2017" (Microsoft (R) C/C++ Optimizing Compiler Version 19.10.25019 for x64).
Microsoft (R) Program Maintenance Utility Version 14.10.25019.0
Copyright (C) Microsoft Corporation. All rights reserved.
[ 7%] Building CXX object CMakeFiles/shared.dir/src/Utf8.cpp.obj
Utf8.cpp
P:\Compilados\x32-x64\TRABAJO_MSVC2017_x64\netlink\include\Utf8.h(167): error C3861: '__lzcnt': identifier not found
P:\Compilados\x32-x64\TRABAJO_MSVC2017_x64\netlink\src\Utf8.cpp(88): note: see reference to function template instantiation 'char32_t utf8::toUtf32<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>(iterator)' being compiled
with
[
iterator=std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>
]
P:\Compilados\x32-x64\TRABAJO_MSVC2017_x64\netlink\include\Utf8.h(167): error C2050: switch expression not integral
NMAKE : fatal error U1077: 'C:\PROGRA~2\MICROS~4\2017\ENTERP~1\VC\Tools\MSVC\1410~1.250\bin\Hostx64\x64\cl.exe' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"c:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.10.25017\bin\HostX64\x64\nmake.exe"' : return code '0x2'
Stop.
NMAKE : fatal error U1077: '"c:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.10.25017\bin\HostX64\x64\nmake.exe"' : return code '0x2'
Thanks in advance!
DJuego
P,S: No problem with Visual Studio 2015
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
linux socket like shell command audit ?
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
Hi! Your netlink library seems interesting. :-) Unfortunately i am a newbie in serialization. I have been studying your examples and I have problems understanding how to deserialize when a socket receives data. And yes . I have read your MsgPack Tutorial. Please. Could you extend the current examples? Could you add new compilable samples with the full serialization/deserialization process? Thanks! :-)
In MsgPack::storeUint16(), reinterpret_cast<uint16_t>(target) results in an unaligned memory access on ARMv5 processors. For example when storeUint16() is called to store a length of 0x15 to MAP_16, it is supposed to change header[1] to 0x15 and header[2] to 0x00. However on ARMv5 processors header[0] is also changed to 0x15.
Suggested fix: Replace pointer deference to memcpy()
More problems with the same code (i have isolated the problems from my super-project. :-D):
[LINK to pastecode]
I feel the code is so big but at least it's complete and it can be run.
I am working in Windows 10 x64 with Visual Studio 2015.
I have two computers in a LAN. The Sender and The Receiver. I am broadcasting UDP packets from the Sender. However i want The Sender can listen too.
a) Yes. The Receiver receive a packet! However socket->receive return 0 bytes!
b) The "workaround" is socket->sgetn... but i suspect it is not the ideal solution...
I have tried to isolate the problem. I think the bug could be in std::streamsize Socket::showmanyc(). (return zero unexpectedly).
Curiously when the code is debugged(breakpoints) std::streamsize Socket::showmanyc(). works well sometimes.
#include <iostream>
#include <chrono>
#include <string>
#include <netLink/netLink.h>
char data[128];
void wait(int milliseconds)
{
std::chrono::high_resolution_clock::time_point end, start;
std::chrono::milliseconds ms;
start = std::chrono::high_resolution_clock::now();
do
{
end = std::chrono::high_resolution_clock::now();
ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
} while (ms.count() < milliseconds);
}
int main(int argc, char** argv) {
//#ifdef WINVER
netLink::init();
//#endif
netLink::SocketManager socketManager;
std::shared_ptr<netLink::Socket> socket = socketManager.newSocket();
try
{
socket->initAsUdpPeer("0.0.0.0", 3015);
}
catch (netLink::Exception exc)
{
std::cout << "Address is already in use" << std::endl;
return 1;
}
socket->setBlockingMode(false);
if (argc > 1)
{
std::cout << "The Receiver" << std::endl;
socketManager.onReceiveRaw = [](netLink::SocketManager *manager, std::shared_ptr< netLink::Socket > socket)
{
std::cout << "Receiving..." << std::endl;
std::size_t size = socket->receive(data, 128); //THIS LINE DOES NOT WORK!
if (size > 0)
{
std::cout << "Incoming data: " << data << std::endl;
}
else
{
std::cout << "NO DATA???" << std::endl;
}
};
while (true)
socketManager.listen(5.0);
}
else
{
std::cout << "The Sender" << std::endl;
socket->setBroadcast(true);
socket->hostRemote = "255.255.255.255";
socket->portRemote = socket->portLocal;
char* data = "My data\0";
while (true)
{
wait(1000);
std::cout << "Sending..." << std::endl;
std::streamsize size = socket->send(data, 128);
}
}
return 0;
}
DJuego
I am trying to create two functions: FromPaqueteToMsgPack and FromMsgPackToPaquete.
int DeMsgPackAPaquete(const std::unique_ptrMsgPack::Element msgpack, Paquete &paquete);
int DePaqueteAMsgPack(const Paquete paquete, std::unique_ptrMsgPack::Element &msgpack);
It works... partially. There are problems with the negative numbers in angulo var. I do not know if the approximation is correct.
It works in Visual Studio. And MinGW gcc 4.9.2 (debug) but in MinGW gcc 5.1.0 there are undefined references :-( Would you guide me?
Thx
Here is the code:
http://paste.ofcode.org/EnwpUuSBX9YMjDWXn8jGVA
Here is the result (MinGW gcc 5.1.0).
g++.exe -Llib\Debug -o bin\Debug\TestRapido.exe obj\Debug\main.o obj\Debug\UtilidadesMsgPack.o -lnetlink
obj\Debug\UtilidadesMsgPack.o: In function `long long MsgPack::Number::getValue<long long>() const':
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:51: undefined reference to `loadFloat32(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:53: undefined reference to `loadFloat64(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:55: undefined reference to `loadUint8(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:57: undefined reference to `loadUint16(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:59: undefined reference to `loadUint32(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:61: undefined reference to `loadUint64(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:63: undefined reference to `loadInt8(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:65: undefined reference to `loadInt16(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:67: undefined reference to `loadInt32(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:69: undefined reference to `loadInt64(unsigned char const*)'
obj\Debug\UtilidadesMsgPack.o: In function `float MsgPack::Number::getValue<float>() const':
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:51: undefined reference to `loadFloat32(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:53: undefined reference to `loadFloat64(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:55: undefined reference to `loadUint8(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:57: undefined reference to `loadUint16(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:59: undefined reference to `loadUint32(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:61: undefined reference to `loadUint64(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:63: undefined reference to `loadInt8(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:65: undefined reference to `loadInt16(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:67: undefined reference to `loadInt32(unsigned char const*)'
P:\Mis-Proyectos\Cross-compilados\EV3\TestRapido/inc/netLink/include/Number.h:69: undefined reference to `loadInt64(unsigned char const*)'
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
21 error(s), 0 warning(s) (0 minute(s), 0 second(s))
Integrating this project as part of a bigger project would be much easier if you adopted CMake and dropped the MSVS silliness and the manual Makefile.
Thank you for sharing this code!
I wrote a tcp client.
When I closed tcp server, the client won't reconnect..
Please teach me how to reconnect the tcp server, Thank's a lot!
Hi,I used vs2015 and the tcp example, but there is a problem
error LNK2019: 无法解析的外部符号 "void __cdecl netLink::init(void)"
what should i do?
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;
}
Hi,
I am Pedro Pareja. I am the author of NetLink Sockets C++ (https://sourceforge.net/projects/netlinksockets/ and now also in https://github.com/PedroPareja/netlink-sockets-cpp).
Your library is based in my work and it would have been nice to include some reference about it. I have noticed in the history of the files that you did at first in the header of the files, but at some point you removed it:
NetLink Sockets: Networking C++ library
Copyright 2012 Pedro Francisco Pareja Ruiz ([email protected])
Modified 2013 Alexander Meißner ([email protected])
This file is part of NetLink Sockets.
NetLink Sockets is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
NetLink Sockets is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with NetLink Sockets. If not, see <http://www.gnu.org/licenses/>.
Apart from that there's a license problem as NetLink Sockets C++ is under the GPL v3 License:
"Permissions of this strong copyleft license are conditioned on making available complete source code of licensed works and modifications, which include larger works using a licensed work, under the same license. Copyright and license notices must be preserved. Contributors provide an express grant of patent rights."
That means that the derived work must preserve the GPL v3 license.
Please fix this licensing problem.
Congrats on your work with the library, keep it up.
#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;
}
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]
Currently you can't really find any kind docs easily. I'm talking Doxygen or something like that.
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);
}
In ndk r10e, when the value of BOOL_FALSE, sputc> 0 is fail to data inconsistencies will happening. If it is changed as follows: I think the best.
streamBuffer-> sputc (type)> 0
↓
streamBuffer-> sputc (type)! = std :: basic_streambuf :: traits_type :: eof ()
@see http://www.dcs.uni-pannon.hu/smidla/web/cplusplus/reference/iostream/streambuf/sputc/index.html
thank you
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
Is there any plans for windows support?
I am trying to understand your code sample in the README:
`
MsgPack::Serializer serializer(socket);
serializer << MsgPack__Factory(ArrayHeader(3)); //Next 3 elements belong in this array
serializer << MsgPack::Factory(true);
serializer << MsgPack__Factory(ArrayHeader(0));
serializer << MsgPack::Factory("Hello World!");`
So I am trying my own example:
`
netLink::SocketManager socketManager;
std::shared_ptr<netLink::Socket> socket = socketManager.newMsgPackSocket();
MsgPack::Serializer serializer(socket.get());
for (auto const & x : namesStringVector) {
serializer << MsgPack::Factory(x);
}
MsgPack::Deserializer deserializer(socket.get());
deserializer.deserialize([](std::unique_ptr<MsgPack::Element> parsed) {
std::cout << "Parsed: " << *parsed << "\n";
return false;
}, true);
`
But I get no output. I suspect my choice of object "socket" for your example is incorrect. I cannot find the information in the TCP/UDP sample code so I thought I'd ask here.
What is the correct initialization and object creation of "socket" in your example? My use case would be more for writing to a local variable rather than actually passing a message using TCP/UDP.
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'
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))(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(
[...]
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
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;
}
Notes:
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 ____".
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.