Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reduced to 2 classes: PassiveSocket and SimpleSocket .. and some more fixes/additions #4

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
322c952
made mingw platform compile statically without dependency to libwinpt…
hayguen Jun 17, 2016
a319476
reduced to 2 classes: PassiveSocket and SimpleSocket
hayguen Jun 17, 2016
2c2edeb
added examples, added inlines/aliases and a few fixes
hayguen Jun 19, 2016
e71b003
silence compiler warnings for switch cases
hayguen Jul 8, 2016
56ddebb
added extra interface functions and extended the examples
hayguen Jul 13, 2016
3fa3ff2
bugfix in SetConnectTimeoutMillis(), optimization and minor enhancements
hayguen Jul 15, 2016
ba677f5
fixed error handling
hayguen Jul 20, 2016
f8bbdea
added EADDRINUSE and printfs (deactivated) for debugging
hayguen Jul 20, 2016
3bee584
several bugfixes/enhancements from 'PROCITEC GmbH' company
hayguen May 3, 2018
2e20bfb
compiler/linker options for build with mingw and msvc
hayguen May 3, 2018
f011324
bugfixes and enhancements on local/peer and bind()
hayguen May 12, 2018
7222078
fix GetIPv4AddrInfo[Static]() with no/empty address string
hayguen May 13, 2018
9cbb2e7
define export/visibility - and it's import for shared library
hayguen Aug 12, 2020
4936c87
added options to allow testing udp multicast
hayguen Aug 23, 2021
1929412
definition CLSOCKET_STATIC_LIB for MSVC to skip dllexport/import
hayguen Oct 28, 2021
cae012d
added TestMaxConnections example - to test file-descriptor limit of s…
hayguen Jul 22, 2023
0ed5dff
minor, typos, ..
ayguen Aug 15, 2023
cf3def4
update/enhance/fix examples
ayguen Aug 17, 2023
d7af35c
CPassiveSocket::Listen() for nPort == 0
ayguen Sep 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 63 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
project(clsocket)


# set up versioning.
set(BUILD_MAJOR "1")
set(BUILD_MINOR "4")
Expand All @@ -19,7 +20,6 @@ src/StatTimer.h

SET(CLSOCKET_SOURCES
src/SimpleSocket.cpp
src/ActiveSocket.cpp
src/PassiveSocket.cpp
)

Expand All @@ -44,6 +44,18 @@ elseif(WIN32)
SET(PROJECT_LIBS Ws2_32.lib)
if(MINGW)
# Special MINGW stuff here
OPTION(CLSOCKET_OWN_INET_PTON "Use own inet_pton() implementation (required on MINGW)" ON)
if(CLSOCKET_OWN_INET_PTON)
add_definitions(-DCLSOCKET_OWN_INET_PTON)
endif()
# see https://cmake.org/pipermail/cmake/2012-September/051970.html
# see http://stackoverflow.com/questions/13768515/how-to-do-static-linking-of-libwinpthread-1-dll-in-mingw
# looks, the following compiler options produce linker errors. -static, .. options should only be used for linker
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static -static-libgcc")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static -static-libgcc -static-libstdc++")
# commenting out upper two CMAKE_C[XX]_FLAG now compiles and links with and without CLSOCKET_SHARED cmake option
set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS} -static -static-libgcc -s")
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "${CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS} -static -static-libgcc -static-libstdc++ -s")
elseif(MSVC)
# Special MSVC stuff here
add_definitions(-D_WINSOCK_DEPRECATED_NO_WARNINGS)
Expand All @@ -63,12 +75,29 @@ if(CLSOCKET_SHARED)
else()
ADD_LIBRARY(clsocket SHARED ${CLSOCKET_SOURCES})
endif()
# linking against shared library requires the symbols
target_compile_definitions(clsocket PRIVATE EXPORT_CLSOCKET_SYMBOLS)
# have internal symbols hidden by default
set_target_properties(clsocket PROPERTIES CXX_VISIBILITY_PRESET hidden)
else()
if(CLSOCKET_DEP_ONLY)
ADD_LIBRARY(clsocket STATIC EXCLUDE_FROM_ALL ${CLSOCKET_SOURCES})
else()
ADD_LIBRARY(clsocket STATIC ${CLSOCKET_SOURCES})
endif()
# no need for export symbols with a static library

if(MSVC)
# Special MSVC stuff here
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -MT")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -MT")
set(CMAKE_C_FLAGS_MINSIZEREL "${CMAKE_C_FLAGS_MINSIZEREL} -MT")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL} -MT")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -MT")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -MT")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -MTd")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -MTd")
endif()
endif()
TARGET_LINK_LIBRARIES(clsocket ${PROJECT_LIBS})

Expand All @@ -83,21 +112,50 @@ endif()
set_target_properties(clsocket PROPERTIES VERSION ${BUILD_VERSION}
SOVERSION ${BUILD_MAJOR})

if(UNIX)
if(UNIX OR (WIN32 OR MINGW))
OPTION(CLSOCKET_EXAMPLES "Build the examples" OFF)

if(CLSOCKET_EXAMPLES)
ADD_EXECUTABLE(clsocket-example examples/RecvAsync.cpp)
TARGET_LINK_LIBRARIES(clsocket-example clsocket pthread)

if (NOT MSVC)
# pthread not available with MSVC
ADD_EXECUTABLE(clsocket-example examples/RecvAsync.cpp)
TARGET_LINK_LIBRARIES(clsocket-example clsocket pthread)
if(NOT CLSOCKET_DEP_ONLY)
install(TARGETS clsocket-example DESTINATION bin)
endif()
endif()

ADD_EXECUTABLE(testmaxconnections-example examples/TestMaxConnections.cpp)
TARGET_LINK_LIBRARIES(testmaxconnections-example clsocket)
if(NOT CLSOCKET_DEP_ONLY)
install(TARGETS clsocket-example DESTINATION bin)
install(TARGETS testmaxconnections-example DESTINATION bin)
endif()
set_target_properties(testmaxconnections-example
PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED YES
CXX_EXTENSIONS NO
)

ADD_EXECUTABLE(querydaytime-example examples/QueryDayTime.cpp)
TARGET_LINK_LIBRARIES(querydaytime-example clsocket)

ADD_EXECUTABLE(echoserver-example examples/EchoServer.cpp)
TARGET_LINK_LIBRARIES(echoserver-example clsocket)

ADD_EXECUTABLE(delayedechoserver-example examples/DelayedEchoServer.cpp)
TARGET_LINK_LIBRARIES(delayedechoserver-example clsocket)

ADD_EXECUTABLE(txtoserver-example examples/TxToServer.cpp)
TARGET_LINK_LIBRARIES(txtoserver-example clsocket)

ADD_EXECUTABLE(udpserver-example examples/UdpServer.cpp)
TARGET_LINK_LIBRARIES(udpserver-example clsocket)

ADD_EXECUTABLE(txtoudpserver-example examples/TxToUdpServer.cpp)
TARGET_LINK_LIBRARIES(txtoudpserver-example clsocket)

endif()
endif()

78 changes: 78 additions & 0 deletions examples/DelayedEchoServer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@

#include "PassiveSocket.h" // Include header for active socket object definition

#define MAX_PACKET 4096


#ifdef WIN32
#include <windows.h>

static void sleep( unsigned int seconds )
{
Sleep( seconds * 1000 );
}
#elif defined(_LINUX) || defined (_DARWIN)
#include <unistd.h>
#endif

int main(int argc, char **argv)
{
CPassiveSocket socket;
CSimpleSocket *pClient = NULL;

const char * bindAddr = 0;
unsigned bindPort = 6789;
if ( argc <= 1 )
fprintf(stderr, "usage: %s [<bind-address> [<bind-port>]]\n", argv[0] );
if ( 1 < argc )
bindAddr = argv[1];
if ( 2 < argc )
bindPort = atoi(argv[2]) & 65535;

//--------------------------------------------------------------------------
// Initialize our socket object
//--------------------------------------------------------------------------
socket.Initialize();
fprintf(stderr, "binding to %s:%u\n", bindAddr, bindPort);
socket.Listen( bindAddr, uint16(bindPort) ); // not "127.0.0.1" to allow testing with remotes

while (true)
{
if ((pClient = socket.Accept()) != NULL)
{
fprintf(stderr, "\nLocal is %s. Local: %s:%u "
, ( pClient->IsServerSide() ? "Server" : "Client" )
, pClient->GetLocalAddr(), (unsigned)pClient->GetLocalPort());
fprintf(stderr, "Peer: %s:%u\n", pClient->GetPeerAddr(), (unsigned)pClient->GetPeerPort());

//----------------------------------------------------------------------
// Receive request from the client.
//----------------------------------------------------------------------
if (pClient->Receive(MAX_PACKET))
{
//------------------------------------------------------------------
// Send response to client and close connection to the client.
//------------------------------------------------------------------
int32 rx = pClient->GetBytesReceived();
uint8 *txt = pClient->GetData();
fprintf(stderr, "received %d bytes:\n", rx );
for ( int k = 0; k < rx; ++k )
fprintf(stderr, "%c", txt[k]);
fprintf(stderr, "\n");
sleep(5);
pClient->Send( txt, rx );
fprintf(stderr, "sent back after 5 seconds\n" );
pClient->Close();
}

delete pClient;
}
}

//-----------------------------------------------------------------------------
// Receive request from the client.
//-----------------------------------------------------------------------------
socket.Close();

return 1;
}
42 changes: 38 additions & 4 deletions examples/EchoServer.cpp
Original file line number Diff line number Diff line change
@@ -1,33 +1,67 @@

#include "PassiveSocket.h" // Include header for active socket object definition

#define MAX_PACKET 4096
#define MAX_PACKET 4096

int main(int argc, char **argv)
{
CPassiveSocket socket;
CActiveSocket *pClient = NULL;

const char * bindAddr = 0;
unsigned bindPort = 6789;
if ( argc <= 1 )
fprintf(stderr, "usage: %s [<bind-address> [<bind-port>]]\n", argv[0] );
if ( 1 < argc )
bindAddr = argv[1];
if ( 2 < argc )
bindPort = atoi(argv[2]) & 65535;

//--------------------------------------------------------------------------
// Initialize our socket object
//--------------------------------------------------------------------------
socket.Initialize();

socket.Listen("127.0.0.1", 6789);
fprintf(stderr, "binding to %s:%u\n", bindAddr, bindPort);
socket.Listen( bindAddr, uint16(bindPort) ); // not "127.0.0.1" to allow testing with remotes

while (true)
{
if ((pClient = socket.Accept()) != NULL)
{
fprintf(stderr, "\nLocal is %s. Local: %s:%u "
, ( pClient->IsServerSide() ? "Server" : "Client" )
, pClient->GetLocalAddr(), (unsigned)pClient->GetLocalPort());
fprintf(stderr, "Peer: %s:%u\n", pClient->GetPeerAddr(), (unsigned)pClient->GetPeerPort());

//----------------------------------------------------------------------
// Receive request from the client.
//----------------------------------------------------------------------

pClient->WaitUntilReadable(100);
int32 peekRx = pClient->GetNumReceivableBytes();

if (pClient->Receive(MAX_PACKET))
{
fprintf(stderr, "\n%s. Local: %s:%u Peer: %s:%u\n"
, ( pClient->IsServerSide() ? "Local is Server" : "Local is Client" )
, pClient->GetLocalAddr(), (unsigned)pClient->GetLocalPort()
, pClient->GetPeerAddr(), (unsigned)pClient->GetPeerPort()
);

//------------------------------------------------------------------
// Send response to client and close connection to the client.
//------------------------------------------------------------------
pClient->Send( pClient->GetData(), pClient->GetBytesReceived() );
int32 rx = pClient->GetBytesReceived();

if ( peekRx != rx && !( peekRx == 0 && rx < 0 ) )
fprintf( stderr, "GetNumReceivableBytes() = %d != %d = Receive() !\n", peekRx, rx );

uint8 *txt = pClient->GetData();
pClient->Send( txt, rx );
fprintf(stderr, "received and sent %d bytes:\n", rx );
for ( int k = 0; k < rx; ++k )
fprintf(stderr, "%c", txt[k]);
fprintf(stderr, "\n");
pClient->Close();
}

Expand Down
10 changes: 9 additions & 1 deletion examples/QueryDayTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,16 @@ int main(int argc, char **argv)
// Create a connection to the time server so that data can be sent
// and received.
//--------------------------------------------------------------------------
if (socket.Open("time-C.timefreq.bldrdoc.gov", 13))
const char * timeServer = ( argc >= 2 ) ? argv[1] : "time-C.timefreq.bldrdoc.gov";
int PortNo = ( argc >= 3 ) ? atoi(argv[2]) : 13;
fprintf(stderr, "trying to connect to timeserver %s:%d ..\n", timeServer, PortNo);
if (socket.Open(timeServer, (uint16)PortNo))
{
fprintf(stderr, "\nLocal is %s. Local: %s:%u "
, ( socket.IsServerSide() ? "Server" : "Client" )
, socket.GetLocalAddr(), (unsigned)socket.GetLocalPort());
fprintf(stderr, "Peer: %s:%u\n", socket.GetPeerAddr(), (unsigned)socket.GetPeerPort());

//----------------------------------------------------------------------
// Send a requtest the server requesting the current time.
//----------------------------------------------------------------------
Expand Down
28 changes: 23 additions & 5 deletions examples/RecvAsync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ void *CreateTCPEchoServer(void *param)
}
}

sleep(100);
sleep(1);

delete pClient;
}
Expand Down Expand Up @@ -78,23 +78,41 @@ int main(int argc, char **argv)
int numBytes = -1;
int bytesReceived = 0;

client.Select();
client.WaitUntilReadable(100); // wait up to 100 ms

while (bytesReceived != strlen(TEST_PACKET))
//while (bytesReceived != strlen(TEST_PACKET))
while ( numBytes != 0 ) // Receive() until socket gets closed
{
int32 peekRx = client.GetNumReceivableBytes();

numBytes = client.Receive(MAX_PACKET);

if ( peekRx != numBytes && !( peekRx == 0 && numBytes < 0 ) )
fprintf( stderr, "\nGetNumReceivableBytes() = %d != %d = Receive() !\n", peekRx, numBytes );

if (numBytes > 0)
{
bytesReceived += numBytes;
memset(result, 0, 1024);
memcpy(result, client.GetData(), numBytes);
printf("received %d bytes: '%s'\n", numBytes, result);
printf("\nreceived %d bytes: '%s'\n", numBytes, result);
}
else if ( CSimpleSocket::SocketEwouldblock == client.GetSocketError() )
fprintf(stderr, ".");
else if ( !client.IsNonblocking() && CSimpleSocket::SocketTimedout == client.GetSocketError() )
fprintf(stderr, "w");
else
{
printf("Received %d bytes\n", numBytes);
printf("\nreceived %d bytes\n", numBytes);

fprintf(stderr, "Error: %s\n", client.DescribeError() );
fprintf(stderr, "Error: %s, code %d\n"
, ( client.IsNonblocking() ? "NonBlocking socket" : "Blocking socket" )
, (int) client.GetSocketError()
);
}

client.WaitUntilReadable(100); // wait up to 100 ms
}
}
}
Expand Down
Loading