dfhack / clsocket Goto Github PK
View Code? Open in Web Editor NEWSimpleSockets is a lightweight set of classes that allow developers to implement IP based network programs.
Home Page: http://sockets.carrierlabs.com/
SimpleSockets is a lightweight set of classes that allow developers to implement IP based network programs.
Home Page: http://sockets.carrierlabs.com/
------------------------------------------------------------------------------------------ * History ------------------------------------------------------------------------------------------ Written by Mark Carrier to provide a mechanism for writing cross platform socket code. This library was originally written to only support blocking TCP sockets. Over the years it has been extended to support UDP and RAW sockets as well. This is the first official release of the library and the following functionality is supported: * Cross platform socket support. o Windows 95, Windows 98, Windows XP o Linux, Unix o Macintosh OSX * Support for sychronious, and asychronious sockets * Supports TCP Streams * Supports UDP Datagrams * Supports Raw Sockets * Thread Safe * Signal Safe ------------------------------------------------------------------------------------------ * Building and Installing ------------------------------------------------------------------------------------------ This is a very small library and is very easy to build and configure. To build and install make sure you are logged in as a user who has access to the recommend GNU installation directories. Then type make -BUILD=Release && make install That is it now you are off and running. NOTE: When using the library with WINDOWS you must define _WIN32 and when using with LINUX you must define _LINUX. ------------------------------------------------------------------------------------------ * SimpleSocket Class Overview ------------------------------------------------------------------------------------------ Network communications via sockets can be abstracted into two categories of functionality; the active socket and the passive socket. The active socket object initiates a connection with a known host, whereas the passive socket object waits (or listens) for inbound requests for communication. The functionality of both objects is identical as far as sending and receiving data. This library makes distinction between the two objects because the operations for constructing and destructing the two are different. This library is different from other socket libraries which define TCP sockets, UDP sockets, HTTP sockets, etc. The reason is the operations required for TCP, UDP, and RAW network communication is identical from a logical stand point. Thus a program could initially be written employing TCP streams, and then at some future point it could be discovered that UDP datagrams would satisify the solution. Changing between the two transport protocols would only require changing how the object is instantiated. The remaining code would in theory require minimal to no changes. This library avoids abstractions like HTTP socket, or SMTP socket, soley because this type of object mixes the application and the transport layer. These types of abstractions can be created using this library as a base class. The simple socket library is comprised of two class which can be used to represent all socket communications. * Active Socket Class * Passive Socket Class ------------------------------------------------------------------------------------------ * SimpleSocket Class Examples ------------------------------------------------------------------------------------------ When operating on a socket object most methods will return true or false Simple Active Socket As mentioned previously the active socket (CActiveSocket) is used to initiate a connections with a server on some known port. So you want to connect to an existing server... How do you do it? There are many ways using the existing Berkley Socket API, but the goal of this class is to remove the many calls and man page lookups and replace them with clear, concise set of methods which allow a developer to focus on the logic of network programming. The following code will connect to a DAYTIME server on port 13, query for the current time, and close the socket. #include <string.h> #include "ActiveSocket.h" // Include header for active socket object definition int main(int argc, char **argv) { CActiveSocket socket; // Instantiate active socket object (defaults to TCP). char time[50]; memset(&time, 0, 50); //-------------------------------------------------------------------------- // Initialize our socket object //-------------------------------------------------------------------------- socket.Initialize(); //-------------------------------------------------------------------------- // Create a connection to the time server so that data can be sent // and received. //-------------------------------------------------------------------------- if (socket.Open("time-C.timefreq.bldrdoc.gov", 13)) { //---------------------------------------------------------------------- // Send a requtest the server requesting the current time. //---------------------------------------------------------------------- if (socket.Send((const uint8 *)"\n", 1)) { //---------------------------------------------------------------------- // Receive response from the server. //---------------------------------------------------------------------- socket.Receive(49); memcpy(&time, socket.GetData(), 49); printf("%s\n", time); //---------------------------------------------------------------------- // Close the connection. //---------------------------------------------------------------------- socket.Close(); } } return 1; } You can see that the amount of code required to an object for network communciation is very small and simple. Simple Passive Socket Now you want to build a server. How do you do it? For a practical test lets build an echo server. The server will listen on port 6789 an repsond back with what ever has been sent to the server. #include <iostream> #include "PassiveSocket.h" // Include header for active socket object definition #define MAX_PACKET 4096 int main(int argc, char **argv) { CPassiveSocket socket; CActiveSocket *pClient = NULL; //-------------------------------------------------------------------------- // Initialize our socket object //-------------------------------------------------------------------------- socket.Initialize(); if (!socket.Listen("127.0.0.1", 6789)) { std::cerr << socket.DescribeError() << std::endl; return 1; } while (socket.IsSocketValid()) { if ((pClient = socket.Accept()) != NULL) { //---------------------------------------------------------------------- // Receive request from the client. //---------------------------------------------------------------------- if (pClient->Receive(MAX_PACKET)) { //------------------------------------------------------------------ // Send response to client and close connection to the client. //------------------------------------------------------------------ pClient->Send( pClient->GetData(), pClient->GetBytesReceived() ); pClient->Close(); } delete pClient; } } //----------------------------------------------------------------------------- // Receive request from the client. //----------------------------------------------------------------------------- socket.Close(); return 1; }
In CSimpleSocket::Initialize
the m_hWSAData
is initialised under Windows using WSAStartup.
According to MSDN, each call to WSAStartup
must have a matching call to WSACleanup.
However, the entire library is lacking such a call: https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsastartup
When frequently creating sockets, sending data, closing and destroying sockets, this might cause resource leaks.
Is this just an oversight?
Best regards
On Windows,
SETSOCKOPT(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&nReuse, sizeof(int32));
SETSOCKOPT(m_socket, IPPROTO_TCP, IP_TOS, &nReuse, sizeof(int32));
is NOT executed, where especially setting SO_REUSEADDR leads to different behaviour,
when closing listening socket .. and trying to listen again within a few seconds.
same behaviour could be achieved, when always calling
CSimpleSocket::SetOptionReuseAddr()
always inside Listen() - as alternative, have it called from outside before calling Listen() - if desired.
The same issue also for IPPROTO_TCP / IP_TOS but this function is missing in CSimpleSocket - for now.
Using a simple:
networkConnection->TranslateSocketError();
CSimpleSocket::CSocketError e = networkConnection->GetSocketError();
networkConnection->DescribeError(e);
Has seemed to error every time. Also, I've been getting -1 from networkConnection->Receive() and when checking the error using the above code, the error is CSimpleSocket::CSocketError::SocketSuccess
.
Line 404 in 8cf9493
the parameter CShutdownMode nShutdown is not used !
I want to use the udp sockets on this library and i dont know how could you make up with a simple example using them.
SimpleSocket.cpp, 502 is nRetVal = (CSocketError)shutdown(m_socket, CSimpleSocket::Sends);
but must be nRetVal = (CSocketError)shutdown(m_socket, nShutdown);
The install is failing on visual studio 2017, on windows 7. I get the following error:
[1/2] Linking CXX shared library clsocket-CMAKE\clsocket.dll
FAILED: clsocket-CMAKE/clsocket.dll clsocket-CMAKE/clsocket.lib
cmd.exe /C "cd . && "C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -E vs_link_dll --intdir=clsocket-CMAKE\CMakeFiles\clsocket.dir --manifests -- C:\PROGRA~2\MIB055~1\2017\PROFES~1\VC\Tools\MSVC\1414~1.264\bin\Hostx86\x86\link.exe /nologo clsocket-CMAKE\CMakeFiles\clsocket.dir\src\SimpleSocket.obj clsocket-CMAKE\CMakeFiles\clsocket.dir\src\ActiveSocket.obj clsocket-CMAKE\CMakeFiles\clsocket.dir\src\PassiveSocket.obj /out:clsocket-CMAKE\clsocket.dll /implib:clsocket-CMAKE\clsocket.lib /pdb:clsocket-CMAKE\clsocket.pdb /dll /version:4.0 /machine:X86 /debug /INCREMENTAL Ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib && cd ."
RC Pass 1: command "rc /foclsocket-CMAKE\CMakeFiles\clsocket.dir/manifest.res clsocket-CMAKE\CMakeFiles\clsocket.dir/manifest.rc" failed (exit code 0) with the following output:
The system cannot find the file specified
ninja: build stopped: subcommand failed.
Install failed.
When trying to use clsocket
without installing it (e.g. with FetchContent
), include path is not set and compilation fails.
With following dummy example:
main.cpp
:
#include <PassiveSocket.h>
int main() {}
CMakeLists.txt
:
project(test_clsocket_cmake LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
include(FetchContent)
FetchContent_Declare(
clsocket
GIT_REPOSITORY https://github.com/DFHack/clsocket.git
)
option(CLSOCKET_SHARED Off)
option(CLSOCKET_DEP_ONLY Off)
FetchContent_MakeAvailable(clsocket)
set(app_ ${PROJECT_NAME})
add_executable(${app_} main.cpp)
target_link_libraries(${app_} clsocket)
Pre-build cmake
stage passes fine, but the build fails:
[main] Building folder: clsocket-cmake
[build] Starting build
[proc] Executing command: /Users/me/brew/bin/cmake --build /Users/me/src/clsocket-cmake/build --config Debug --target all --
[build] [1/2 50% :: 0.057] Building CXX object CMakeFiles/test_clsocket_cmake.dir/main.o
[build] FAILED: CMakeFiles/test_clsocket_cmake.dir/main.o
[build] /usr/bin/clang++ -g -arch x86_64 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -std=gnu++17 -MD -MT CMakeFiles/test_clsocket_cmake.dir/main.o -MF CMakeFiles/test_clsocket_cmake.dir/main.o.d -o CMakeFiles/test_clsocket_cmake.dir/main.o -c /Users/me/src/clsocket-cmake/main.cpp
[build] /Users/me/src/clsocket-cmake/main.cpp:1:10: fatal error: 'PassiveSocket.h' file not found
[build] #include <PassiveSocket.h>
[build] ^~~~~~~~~~~~~~~~~
[build] 1 error generated.
[build] ninja: build stopped: subcommand failed.
[proc] The command: /Users/me/brew/bin/cmake --build /Users/me/src/clsocket-cmake/build --config Debug --target all -- exited with code: 1 and signal: null
[build] Build finished with exit code 1
If You can add surpport IPv6, it will be awesome~
#define EXPORT __declspec(dllexport)
is defined in Host.h include from other public headers (SimpleSocket.h), with guard #ifdef _MSC_VER
.
however this definition might collide easily with user code using CLsocket.
i'd suggest to rename EXPORT into CLSOCKET_EXPORT ..
[ and possibly make this definition only when having an additional private definition in CMakeLists.txt, e.g. when compiling the shared library ]
most methods in the classes are virtual.
i don't see any obvious reason for this - and tend to remove the "virtual" keyword!
am i wrong?
Hello Mark,
The clsocket library looks well structured and suited to handle many socket applications in one shot.
I like it a lot!
I also like the abundance of comments ! Fantastic !
Just one question:
In the CStatTimer class I see you don't QueryPerformanceFrequency for WIN32.
How do you get accurate time based counts without doing that ? Whats the secret ?
The way understand QueryPerformanceCounter just gets a count/tick...but you need to combine it with the Frequency to get a time based count ?
Thanks & Cheers
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.