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

Fixed incorrect email on my past comment. #44

Closed
wants to merge 258 commits into from
Closed
Changes from 1 commit
Commits
Show all changes
258 commits
Select commit Hold shift + click to select a range
c8c549e
simplifying cmake structure
andreacasalino Jan 29, 2021
0925fee
refactoring
andreacasalino Jan 30, 2021
2d22650
async reintroduced
andreacasalino Jan 30, 2021
8b4a731
implementing crypted socket
andreacasalino Jan 31, 2021
0645d8d
crypto socket removed
andreacasalino Jan 31, 2021
1be64fb
implementing samples
andreacasalino Jan 31, 2021
5ae3e6e
making virtual override public
andreacasalino Jan 31, 2021
736cfbe
code refactored
andreacasalino Feb 7, 2021
48aabbc
fixing samples
andreacasalino Feb 7, 2021
e684fcd
tcp samples implemented
andreacasalino Feb 7, 2021
7981a3b
async responder implemented
andreacasalino Feb 7, 2021
caaaa10
fixing Linux compile errors
andreacasalino Feb 7, 2021
16a0f9a
link to pthreads to solve compile problems
andreacasalino Feb 7, 2021
30fff79
udp samples implemented
andreacasalino Feb 7, 2021
b2f9849
debugging samples
andreacasalino Feb 8, 2021
1507cdb
tcp samples debugged
andreacasalino Feb 8, 2021
445d5da
tcp samples refactored
andreacasalino Feb 9, 2021
550821b
udp samples restructured
andreacasalino Feb 9, 2021
d25ce01
samples working but not robustly
andreacasalino Feb 10, 2021
8801c93
Merge pull request #2 from andreacasalino/ReshapeSamples
andreacasalino Feb 10, 2021
b855bbd
minor changes
andreacasalino Feb 10, 2021
d7e0031
readme of samples added
andreacasalino Feb 10, 2021
80fa72a
handshake in udp server sample added
andreacasalino Feb 10, 2021
aba58cc
minor changes
andreacasalino Feb 10, 2021
ba596b4
sleep in process launcher added
andreacasalino Feb 10, 2021
246ae5f
launcher linux compile error fixed
andreacasalino Feb 13, 2021
8d0c9b6
async sample added
andreacasalino Feb 13, 2021
919a339
debugging asybc sample
andreacasalino Feb 13, 2021
6c6c865
class documentation improved
andreacasalino Feb 13, 2021
3113a59
removing external receive from async shell
andreacasalino Feb 13, 2021
69cac7b
samples debugged
andreacasalino Feb 13, 2021
7e56c85
Merge pull request #3 from andreacasalino/Improving
andreacasalino Feb 13, 2021
eb206dc
Update README.md
andreacasalino Mar 9, 2021
4681b82
Update README.md
andreacasalino Mar 9, 2021
7240df3
mutex protecting send and receive introduced
andreacasalino Mar 9, 2021
edfd7fc
Merge pull request #4 from andreacasalino/promote-thread-safety
andreacasalino Mar 9, 2021
60d3dbd
ci pipeline created
andreacasalino Mar 10, 2021
c6a2010
Merge pull request #5 from andreacasalino/CI-pipeline
andreacasalino Mar 10, 2021
126073e
shared and static libraries compiled
andreacasalino Mar 10, 2021
a948570
Merge pull request #6 from andreacasalino/CI-pipeline
andreacasalino Mar 10, 2021
a4517ae
yaml file modified to separate names
andreacasalino Mar 10, 2021
a59f03c
Update README.md
andreacasalino Mar 10, 2021
bf3c95b
Update README.md
andreacasalino Mar 30, 2021
8be8a18
Update README.md
andreacasalino Mar 30, 2021
d7d1164
async separated from sync
andreacasalino May 1, 2021
727b055
minor changes
andreacasalino May 1, 2021
6920099
implementing new structure
andreacasalino May 2, 2021
9865593
minor changes
andreacasalino May 2, 2021
5e12e0f
implementing tests
andreacasalino May 3, 2021
63ec85f
implementing tests
andreacasalino May 3, 2021
e0e2d8c
implementing async
andreacasalino May 4, 2021
4c074c4
made compilable
andreacasalino May 6, 2021
5f3e5f8
implementing
andreacasalino May 6, 2021
49af2e9
implementing tests
andreacasalino May 7, 2021
ccd3c77
unit test and artifacts workflow split
andreacasalino May 7, 2021
c81ed36
implementing tests
andreacasalino May 7, 2021
ecdd226
restoring samples
andreacasalino May 7, 2021
04b2cbb
implementing
andreacasalino May 7, 2021
a6a0792
launchers modified
andreacasalino May 8, 2021
eceb9bf
samples fixed on Windows
andreacasalino May 8, 2021
94cab0d
samples fixed in Linux
andreacasalino May 8, 2021
6c5a866
implementing tests
andreacasalino May 8, 2021
c91ebfc
documentation updated
andreacasalino May 8, 2021
9477017
minor changes
andreacasalino May 8, 2021
f0ea51f
implementing
andreacasalino May 9, 2021
313f47e
fixing tests
andreacasalino May 9, 2021
7754962
tests fixed
andreacasalino May 9, 2021
ecdefaf
minor changes
andreacasalino May 9, 2021
e50c479
Merge pull request #7 from andreacasalino/GoogleTest
andreacasalino May 9, 2021
1596f54
udp server test disabled
andreacasalino May 11, 2021
50ea08f
Merge pull request #8 from andreacasalino/UnitTestFix
andreacasalino May 11, 2021
2cf5918
improving existing code
andreacasalino May 15, 2021
1e0af87
implementing typed connections
andreacasalino May 15, 2021
dd92a3c
implementing typed messangers
andreacasalino May 16, 2021
7c90215
implementing typed connections
andreacasalino May 16, 2021
6c9cdac
typed tests introduced
andreacasalino May 19, 2021
a0f0bff
implementing tests
andreacasalino May 19, 2021
6d8e881
implementing tests
andreacasalino May 19, 2021
c319c43
typed tests implemented
andreacasalino May 19, 2021
2570a5b
tests added to pipeline
andreacasalino May 19, 2021
83a6207
fix compile error
andreacasalino May 19, 2021
6dbf11c
restructure of cmake prj
andreacasalino May 19, 2021
6b4295b
readme improved
andreacasalino May 19, 2021
2a2b577
Merge pull request #9 from andreacasalino/TypedConnections
andreacasalino May 19, 2021
47bba63
Update README.md
andreacasalino May 21, 2021
00ad331
improving yml file
andreacasalino Jul 16, 2021
8b8a703
Merge pull request #10 from andreacasalino/GitActionImproved
andreacasalino Jul 16, 2021
1942a9a
fetch gtest
andreacasalino Nov 22, 2021
81c41a0
fecth gtest
andreacasalino Nov 22, 2021
36eff91
Merge pull request #11 from andreacasalino/FetchGtest
andreacasalino Nov 22, 2021
7073b3a
refactoring
May 6, 2022
f2bd81c
refactoring
May 6, 2022
de1f224
refactoring
May 6, 2022
3ba189c
refactoring
May 6, 2022
75de698
refactoring
May 6, 2022
e22b153
refactoring
May 6, 2022
1afd32f
refactoring
May 7, 2022
cd51b29
refactoring
May 7, 2022
7ae23f4
refactoring
May 7, 2022
1072f2b
refactoring
May 7, 2022
75b31b6
preparing for tests
May 7, 2022
500b08a
fixing win32 compile
andreacasalino May 7, 2022
f9698c2
testing
May 7, 2022
aa64eed
refactoring
May 8, 2022
a13ce73
refactoring
May 8, 2022
e4d293c
refactoring
May 8, 2022
6a4fef6
refactoring
May 8, 2022
a7ce643
testing
May 8, 2022
195918f
testing
May 8, 2022
2468f2d
testing
May 8, 2022
083bb57
any port bindable
May 8, 2022
c3e6070
open con timeout
May 8, 2022
25995bd
refactoring
May 9, 2022
8892687
refactoring
May 9, 2022
c9ed06b
refactoring
May 9, 2022
4de9b80
clear buffer before receive
May 9, 2022
52c3973
udp socket only send removed
May 9, 2022
a46071e
refactoring
May 9, 2022
a0f4966
testing
May 9, 2022
3cf960b
testing
May 9, 2022
2038e9d
testing
May 9, 2022
6ef909d
testing
May 9, 2022
3c46f8e
testing
May 9, 2022
6225612
refactoring
May 9, 2022
5f2c1b5
testing
May 9, 2022
dcd80bc
testing for timeout functions
May 9, 2022
0af20ec
testing
May 9, 2022
b131f0c
enabling ci tests
May 9, 2022
0921275
enabling artifats ci
May 9, 2022
ab69784
fixing windows compile errors
andreacasalino May 9, 2022
d6238a6
better WSData handling
andreacasalino May 9, 2022
032f926
control over listen backlog size
May 11, 2022
a0c8bc2
better socket error with code
May 11, 2022
322c500
testing
May 11, 2022
4aa4862
testing
May 11, 2022
c715939
testing
May 11, 2022
3883994
fixing compile issue
May 11, 2022
c22ba4a
fixing compile error
May 11, 2022
d660c54
testing
May 11, 2022
a4e2a86
testing
May 11, 2022
f337301
testing
May 12, 2022
7122f81
testing
May 12, 2022
d898520
testing
May 12, 2022
8d7c630
testing
May 12, 2022
828b177
testing
May 12, 2022
337ff44
testing
May 12, 2022
0c15e9e
minor changes
andreacasalino May 12, 2022
1ed52d9
testing
May 12, 2022
3509c26
finxing compile error
andreacasalino May 12, 2022
9626fd2
set WSA version possible
andreacasalino May 12, 2022
73856d8
trying windows 2019
andreacasalino May 12, 2022
31fd514
timeout error
May 12, 2022
0d22e9d
timeout error
May 12, 2022
2b15b64
try within timeout generalized
May 13, 2022
b6ce90d
refactoring
May 13, 2022
12eb10b
removing expected
May 13, 2022
34ae0cc
testing
May 13, 2022
0083a15
testing
May 13, 2022
92e92f9
testing accept with timeout
May 13, 2022
d3711a7
minor change
May 13, 2022
a8e6fae
removing redundant headers
May 13, 2022
82cc148
removing redundnat include
May 13, 2022
712ab6f
refactoring
May 13, 2022
b4a6cfa
minor changes
May 13, 2022
75d5ff1
samples
May 14, 2022
1293d49
testing
andreacasalino May 14, 2022
2825068
testing
andreacasalino May 14, 2022
819e3c1
samples
May 14, 2022
15f37c8
samples
May 14, 2022
643de44
samples
May 14, 2022
ac8fc89
samples
May 14, 2022
ab0d276
samples
May 14, 2022
0590a32
samples
May 14, 2022
53e0b13
samples
May 14, 2022
cafd41c
samples
May 14, 2022
cc0f9a9
refactoring
May 14, 2022
7524a8a
samples
May 15, 2022
16a3678
samples
May 15, 2022
249234e
samples
May 15, 2022
c8f6496
samples
May 15, 2022
e2ef0e3
samples
May 15, 2022
fb612bf
samples
May 15, 2022
d5332ab
samples
andreacasalino May 15, 2022
fb75ad1
enum class
May 15, 2022
a6ca0c0
documenting
May 15, 2022
83d0fbb
documenting
May 15, 2022
83fdfb9
documenting
May 15, 2022
b8bbffc
documenting
May 15, 2022
2391775
static error if not valid os
May 15, 2022
5481270
testing
May 15, 2022
3632e0a
Merge branch 'Refactoring' of github.com:andreacasalino/Cross-Platfor…
May 15, 2022
5370587
testing
May 17, 2022
02b115c
testing
May 17, 2022
2547660
testing
May 17, 2022
a158430
testing
May 17, 2022
f2bf3c7
refactoring
May 17, 2022
059962a
testing
May 17, 2022
0d15e79
testing
May 17, 2022
15c82ca
documenting
May 18, 2022
4369300
documenting
May 18, 2022
823ab3d
documenting
May 19, 2022
9dad15d
documenting
May 19, 2022
d687b73
documenting
May 19, 2022
cac71a0
testing macOS
May 19, 2022
68e57fb
testing mac os
May 19, 2022
e4e6d55
support for mac os
May 19, 2022
dfd3b45
using inet_pton also in windows
andreacasalino May 19, 2022
1c5f932
minor
May 19, 2022
1ede46e
Merge branch 'Refactoring' of github.com:andreacasalino/Cross-Platfor…
May 19, 2022
90b0935
clone functions
May 19, 2022
40fd7b3
refactoring
May 19, 2022
70a5c16
refactoring
May 19, 2022
e8bf468
Merge pull request #12 from andreacasalino/Refactoring
andreacasalino May 19, 2022
bc89e8a
picture
May 19, 2022
90a7b41
Merge branch 'Refactoring'
May 19, 2022
230ddcc
picture
May 19, 2022
5eb088a
fixing tests
May 19, 2022
216c79e
fixing tests
May 19, 2022
7e95caa
Merge pull request #13 from andreacasalino/FixingFailingTests
andreacasalino May 19, 2022
c87d6bc
Update README.md
andreacasalino May 20, 2022
98c31bf
Update README.md
andreacasalino May 20, 2022
5a6530f
Update README.md
andreacasalino May 28, 2022
3e1b366
fixing cmake include
andreacasalino Jul 22, 2022
42cb9a5
Merge pull request #15 from andreacasalino/BetterCMake
andreacasalino Jul 22, 2022
952b782
avoid compile readme
andreacasalino Aug 21, 2022
54549ab
Merge pull request #17 from andreacasalino/AvoidReadMeCompile
andreacasalino Aug 21, 2022
4d24412
simpler cmake
May 28, 2023
256a650
Merge pull request #24 from andreacasalino/SimplerCmakeBarrierInstead…
andreacasalino May 29, 2023
6c7870b
Monitor.pt script
Jun 2, 2023
c5d3014
Merge pull request #25 from andreacasalino/SamplesWithPythonPopen
andreacasalino Jun 5, 2023
4de1b4b
avoid to fetch samples in readme sample
Jun 12, 2023
3e50a30
Merge pull request #27 from andreacasalino/BetterReadmeCmakeSupport
andreacasalino Jun 12, 2023
bddb6c9
use clang-17 for ubuntu-clang format as workaround to github action bug
Dec 23, 2023
ef01be4
Merge pull request #31 from andreacasalino/FixClangIssue
andreacasalino Dec 23, 2023
7d6ae74
auto detect tests labels in runTests CI action
Dec 23, 2023
4cbc4b2
Merge pull request #32 from andreacasalino/AutodetectTests
andreacasalino Dec 23, 2023
023700b
fixed errors when using wasm emscripten.
LostbBlizzard Dec 20, 2023
2d28d38
Merge pull request #33 from andreacasalino/LostbBlizzard-PR
andreacasalino Dec 23, 2023
813d6da
GNU LICENSE added
Feb 8, 2024
9633671
Merge pull request #35 from andreacasalino/WithLicense
andreacasalino Feb 8, 2024
f74355e
avoid custom target command in VisualStudio in favour of a Popen C++ …
andreacasalino Feb 19, 2024
af13292
Merge pull request #37 from andreacasalino/Popen
andreacasalino Feb 20, 2024
81386a9
cosmetic changes to Monitor.py
Feb 20, 2024
bbd3f4b
Merge pull request #38 from andreacasalino/BetterMonitorPy
andreacasalino Feb 20, 2024
cca045c
Refactoring + doc improved
Feb 24, 2024
e692da0
Merge pull request #39 from andreacasalino/Refactoring
andreacasalino Feb 24, 2024
47b0bf7
non blocking semantics for receiving soeckts and the tcp acceptor
Feb 25, 2024
5f4fb06
Merge pull request #40 from andreacasalino/NonBlocking
andreacasalino Mar 31, 2024
00669ff
fix missing include
2bbb May 24, 2024
7585477
Merge pull request #43 from 2bbb/PR/fix_missing_include
andreacasalino May 26, 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
Prev Previous commit
Next Next commit
refactoring
andreacasalino committed Jan 30, 2021
commit 0925feeaf01a451d49e3958dca6433eb37e6bc15
41 changes: 41 additions & 0 deletions CrossSocket/include/Messanger.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* Author: Andrea Casalino
* Created: 01.28.2020
*
* report any bug to andrecasa91@gmail.com.
**/

#ifndef _CROSS_SOCKET_MESSANGER_H_
#define _CROSS_SOCKET_MESSANGER_H_

#include <chrono>

namespace sck {
/**
* @brief The interface providing functionalities for exchanging data
*/
template<typename Send_t, typename Recv_t>
class Messanger {
public:
Messanger() = default;
Messanger(const Messanger&) = delete;
Messanger& operator=(const Messanger&) = delete;

virtual ~Messanger();

/**
* @return true if the message was completely sent
* @param[in] the message to send
*/
virtual bool send(const Send_t& message) = 0;

/**
* @return the number of received bytes
* @param[in] the recepient
* @param[in] the timeout to consider
*/
virtual std::size_t receive(Recv_t& message, const std::chrono::milliseconds& timeout) = 0;
};
}

#endif
40 changes: 40 additions & 0 deletions CrossSocket/include/MessangerConcrete.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Author: Andrea Casalino
* Created: 01.28.2020
*
* report any bug to andrecasa91@gmail.com.
**/

#ifndef _CROSS_SOCKET_MESSANGERCONCRETE_H_
#define _CROSS_SOCKET_MESSANGERCONCRETE_H_

#include <Messanger.h>
#include <utility>
#include <memory>

namespace sck {
/**
* @brief interface to the socket APIs
*/
class Handler;

class MessangerConcrete
: public Messanger<
std::pair<const char*, std::size_t>,
std::pair<char*, std::size_t>
> {
private:
bool send(const std::pair<const char*, std::size_t>& message) final;

std::size_t receive(std::pair<char*, std::size_t>& message, const std::chrono::milliseconds& timeout) final;

std::chrono::milliseconds actualTimeOut = std::chrono::milliseconds(0);

std::shared_ptr<Handler> messageChannel;

protected:
MessangerConcrete(std::shared_ptr<Handler> messageChannel);
};
}

#endif
56 changes: 56 additions & 0 deletions CrossSocket/include/MessangerDecorator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* Author: Andrea Casalino
* Created: 01.28.2020
*
* report any bug to andrecasa91@gmail.com.
**/

#ifndef _CROSS_SOCKET_MESSANGERDECORATOR_H_
#define _CROSS_SOCKET_MESSANGERDECORATOR_H_

#include <MessangerConcrete.h>
#include <vector>

namespace sck {
/**
* @brief The interface providing functionalities for exchanging data
*/
template<typename Send_t, typename Recv_t>
class MessangerDecorator {
private:
bool send(const Send_t& message) final {
this->encode(message);
this->messanger->send({this->sendBuffer.data(), this->sendBuffer.size()});
};

std::size_t receive(Recv_t& message, const std::chrono::milliseconds& timeout) final {
auto recvBytes = this->messanger->receive({this->recvBuffer.data(), this->recvBuffer.capacity()}, timeout);
if(recvBytes != this->recvBuffer.capacity()) {
this->recvBuffer.resize(recvBytes);
}
this->decode(message);
return recvBytes;
};

protected:
MessangerDecorator(MessangerConcrete& mess, const std::size_t recvCapacity) {
this->messanger = &mess;
this->recvBuffer.resize(recvCapacity);
};
MessangerConcrete* messanger;

/**
* @brief write the message into sendBuffer, as a series of raw bytes
*/
virtual encode(const Send_t& message) = 0;
std::vector<char> sendBuffer;

/**
* @brief convert the content of recvBuffer as a received message
*/
virtual decode(Recv_t& message) = 0;
std::vector<char> recvBuffer;
};
}

#endif
40 changes: 5 additions & 35 deletions CrossSocket/include/Socket.h
Original file line number Diff line number Diff line change
@@ -8,55 +8,25 @@
#ifndef _CROSS_SOCKET_SOCKET_H_
#define _CROSS_SOCKET_SOCKET_H_

#include <Address.h>
#include <atomic>
#include <chrono>

namespace sck {
/**
* @brief interface to the socket APIs
*/
class SocketHandler;

namespace sck {
/**
* @brief The interface every socket must derive from.
*/
class Socket {
public:
Socket() = default;
Socket(const Socket&) = delete;
Socket& operator=(const Socket&) = delete;

virtual ~Socket();

void open(const std::chrono::milliseconds& timeout = std::chrono::milliseconds(0));

void close();

inline bool isOpen() const { return this->opened; }

protected:
Socket();
/**
* @param[in] an already created handler to steal
*/
Socket(std::unique_ptr<SocketHandler> channel);

virtual void openConnection() = 0;

virtual void closeConnection();

std::unique_ptr<SocketHandler> channel;

virtual void initHandle() = 0;

/**
* @brief The value should be deduced from object to object
*/
virtual sck::Family getFamily() = 0;
virtual void open(const std::chrono::milliseconds& timeout) = 0;

void bindToPort(const std::uint16_t& port);
virtual void close() = 0;

std::atomic_bool opened;
virtual bool isOpen() const = 0;
};
}

40 changes: 12 additions & 28 deletions CrossSocket/include/SocketClient.h
Original file line number Diff line number Diff line change
@@ -8,61 +8,45 @@
#ifndef _CROSS_SOCKET_SOCKETCLIENT_H_
#define _CROSS_SOCKET_SOCKETCLIENT_H_

#include "Socket.h"
#include <SocketConcrete.h>
#include <MessangerConcrete.h>

namespace sck {
/**
* @brief this is the abstract base class for every implementation of a concrete socket client (tcp or udp)
*/
class SocketClient
: public Socket {
: public SocketConcrete
, public MessangerConcrete {
public:
~SocketClient() override = default;

/**
* @brief returns the address of the remote entity connected with this socket
*/
const sck::Address& getRemoteAddress() const;

/**
* @brief returns the number of bytes actually sent.
* @param[in] the buffer storing the bytes to send
* @param[in] the buffer size
*/
std::size_t send(const char* buffer, const std::size_t& length);

/**
* @brief returns the number of bytes actually received until the timeout fires.
* When passing a timeout equal to 0, a blocking receive is started,
* otherwise the baytes to receive are waited till timeout
* @param[in] the buffer storing the bytes to receive
* @param[in] the buffer capacity
* @param[in] the timeout to consider
*/
std::size_t receive(char* buffer, const std::size_t& length, const std::chrono::milliseconds& timeout = std::chrono::milliseconds(0));
inline const sck::Address& getRemoteAddress() const { return this->remoteAddress; };

protected:
/**
* @param[in] the address of the server to hit
*/
SocketClient(const sck::Address& remoteAddress);
/**
* @param[in] the address of the server to hit
* @param[in] the remote address already connected
* @param[in] an already created handler to steal
*/
SocketClient(const sck::Address& remoteAddress, std::unique_ptr<SocketHandler> channel);

sck::Family getFamily() final;
SocketClient(const sck::Address& remoteAddress, std::shared_ptr<Handler> channel);

void openConnection() override;
/**
* @brief connect is internally called
*/
void openSpecific() override;

/**
* @brief address of the server connected to this socket
*/
sck::Address remoteAddress;

private:
std::chrono::milliseconds actualTimeOut;
inline sck::Family getFamily() const final { return this->remoteAddress.getFamily(); };
};
}

55 changes: 55 additions & 0 deletions CrossSocket/include/SocketConcrete.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Author: Andrea Casalino
* Created: 01.28.2020
*
* report any bug to andrecasa91@gmail.com.
**/

#ifndef _CROSS_SOCKET_SOCKETCONCRETE_H_
#define _CROSS_SOCKET_SOCKETCONCRETE_H_

#include <Socket.h>
#include <Address.h>

namespace sck {
enum Protocol { UDP, TCP };

/**
* @brief interface to the socket APIs
*/
class Handler;

/**
* @brief The interface every socket must derive from.
*/
class SocketConcrete : public Socket {
public:
~SocketConcrete();

private:
void open(const std::chrono::milliseconds& timeout) final;

void close() final;

bool isOpen() const;

protected:
SocketConcrete(std::shared_ptr<Handler> channel);

virtual void openSpecific() = 0;

virtual void closeSpecific();

/**
* @brief These values should be internally deduced from object to object
*/
virtual sck::Family getFamily() const = 0;
virtual sck::Protocol getProtocol() const = 0;

void bindToPort(const std::uint16_t& port);

std::shared_ptr<Handler> channel;
};
}

#endif
33 changes: 33 additions & 0 deletions CrossSocket/include/SocketDecorator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/**
* Author: Andrea Casalino
* Created: 01.28.2020
*
* report any bug to andrecasa91@gmail.com.
**/

#ifndef _CROSS_SOCKET_SOCKETDECORATOR_H_
#define _CROSS_SOCKET_SOCKETDECORATOR_H_

#include <Socket.h>
#include <memory>

namespace sck {
/**
* @brief The interface every socket must derive from.
*/
class SocketDecorator : public Socket {
private:
inline void open(const std::chrono::milliseconds& timeout) override { this->wrapped->open(timeout); };

inline void close() override { this->wrapped->close(); };

inline bool isOpen() const override { return this->wrapped->isOpen(); };

protected:
SocketDecorator(std::unique_ptr<Socket> wrapped);

std::unique_ptr<Socket> wrapped;
};
}

#endif
41 changes: 0 additions & 41 deletions CrossSocket/include/SocketServer.h

This file was deleted.

35 changes: 0 additions & 35 deletions CrossSocket/include/async/AsyncClient.h

This file was deleted.

64 changes: 0 additions & 64 deletions CrossSocket/include/async/AsyncService.h

This file was deleted.

28 changes: 0 additions & 28 deletions CrossSocket/include/async/AsyncTcpServer.h

This file was deleted.

20 changes: 0 additions & 20 deletions CrossSocket/include/async/ClientListener.h

This file was deleted.

22 changes: 0 additions & 22 deletions CrossSocket/include/async/ErrorListener.h

This file was deleted.

20 changes: 0 additions & 20 deletions CrossSocket/include/async/MessageListener.h

This file was deleted.

51 changes: 0 additions & 51 deletions CrossSocket/include/async/Service.h

This file was deleted.

7 changes: 3 additions & 4 deletions CrossSocket/include/tcp/TcpClient.h
Original file line number Diff line number Diff line change
@@ -23,13 +23,12 @@ namespace sck::tcp {
* @param[in] the address of the server to reach
*/
explicit TcpClient(const sck::Address& remoteAddress);

~TcpClient() override = default;

protected:
explicit TcpClient(const sck::Address& remoteAddress, std::unique_ptr<SocketHandler> channel);
TcpClient(const sck::Address& remoteAddress, std::shared_ptr<Handler> channel);

void initHandle() final;
private:
inline sck::Protocol getProtocol() const final { return Protocol::TCP; };
};
}

17 changes: 9 additions & 8 deletions CrossSocket/include/tcp/TcpServer.h
Original file line number Diff line number Diff line change
@@ -8,36 +8,37 @@
#ifndef _CROSS_SOCKET_TCPSERVER_H_
#define _CROSS_SOCKET_TCPSERVER_H_

#include <SocketServer.h>
#include "SocketClient.h"
#include <SocketClient.h>

namespace sck::tcp {
/**
* @brief interface for a tcp server.
* When calling open, the server binds and listen to the port, in order to be later ready to accept clients
*/
class TcpServer
: public SocketServer {
: public SocketConcrete {
public:
/**
* @param[in] the port to reserve
* @param[in] the expected protocol family of the client to accept
*/
explicit TcpServer(const std::uint16_t& port, const Family& family = Family::IP_V4);

~TcpServer() override = default;

/**
* @brief Wait for a new client to ask the connection and after accepting it
* returns an interface to use for exchanging data to and from the accepted clients.
* This is a blocking operation.
*/
std::unique_ptr<SocketClient> acceptClient();

protected:
void initHandle() final;
private:
void openSpecific() override;

inline sck::Family getFamily() const final { return this->protocol; };
inline sck::Protocol getProtocol() const final { return Protocol::TCP; };

void openConnection() override;
std::uint16_t port;
sck::Family protocol;
};
}

9 changes: 4 additions & 5 deletions CrossSocket/include/udp/UdpClient.h
Original file line number Diff line number Diff line change
@@ -28,14 +28,13 @@ namespace sck::udp {
*/
UdpClient(const sck::Address& remoteAddress, const std::uint16_t& localPort = 0);

~UdpClient() override = default;

protected:
void initHandle() final;
std::uint16_t port;

void openConnection() override;
void openSpecific() override;

std::uint16_t port;
private:
inline sck::Protocol getProtocol() const final { return Protocol::UDP; };
};
}

6 changes: 2 additions & 4 deletions CrossSocket/include/udp/UdpServer.h
Original file line number Diff line number Diff line change
@@ -27,10 +27,8 @@ namespace sck::udp {
*/
UdpServer(const std::uint16_t& localPort, const sck::Family& protocol = sck::Family::IP_V4);

~UdpServer() override = default;

protected:
void openConnection() final;
private:
void openSpecific() final;
};
}

2 changes: 1 addition & 1 deletion CrossSocket/src/Address.cpp
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
**/

#include <Address.h>
#include "SocketHandler.h"
#include "Handler.h"

namespace sck {
static const std::string LOCALHOST_IPv4 = "127.0.0.1";
234 changes: 234 additions & 0 deletions CrossSocket/src/Handler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
/**
* Author: Andrea Casalino
* Created: 01.28.2020
*
* report any bug to andrecasa91@gmail.com.
**/

#include "Handler.h"
#include <sstream>
#include <Error.h>

#ifdef _WIN32
#include <ws2tcpip.h>
#else
#include <netdb.h>
#endif

namespace sck {
#ifdef _WIN32
std::shared_ptr<SocketHandler::WSAManager> SocketHandler::WSAManager::managerInstance;

std::shared_ptr<SocketHandler::WSAManager> SocketHandler::WSAManager::getManager() {
if (nullptr == managerInstance) {
managerInstance = std::shared_ptr<SocketHandler::WSAManager>(new SocketHandler::WSAManager()); //not possible to call make_shared because c'tor is private
}
return managerInstance;
}

SocketHandler::WSAManager::WSAManager() {
WSADATA wsa;
WSAStartup(MAKEWORD(2, 0), &wsa);
}

SocketHandler::WSAManager::~WSAManager() {
WSACleanup();
}
#endif

int getLastError() {
#ifdef _WIN32
return WSAGetLastError();
#else
return static_cast<int>(errno);
#endif
}

void throwWithCode(const std::string& what){
std::stringstream s;
s << what << " , error code: " << getLastError();
throw Error(s.str());
}

std::unique_ptr<SocketAddressIn_t> convertIpv4(const sck::Address& address) {
auto tryConversion = [](SocketAddressIn_t& recipient, const sck::Address& address) -> bool {
#if !defined(_WIN32)
in_addr ia;
if (1 == ::inet_pton(AF_INET, address.getHost().c_str(), &ia)) {
recipient.sin_addr.s_addr = ia.s_addr;
return true;
}
#endif

addrinfo* res, hints = addrinfo{};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;

int gai_err = ::getaddrinfo(address.getHost().c_str(), NULL, &hints, &res);

#if !defined(_WIN32)
if (gai_err == EAI_SYSTEM) {
return false;
}
#endif
if (gai_err != 0) {
return false;
}

auto ipv4 = reinterpret_cast<sockaddr_in*>(res->ai_addr);
::freeaddrinfo(res);
recipient.sin_addr.s_addr = ipv4->sin_addr.s_addr;
return true;
};

if (sck::Family::IP_V4 == address.getFamily()) {
std::unique_ptr<SocketAddressIn_t> resolved = std::make_unique<SocketAddressIn_t>();
// set everything to 0 first
::memset(&(*resolved), 0, sizeof(SocketAddressIn_t));
resolved->sin_family = AF_INET;
if (!tryConversion(*resolved, address)) {
return nullptr;
}
resolved->sin_port = htons(address.getPort());
return resolved;
}
return nullptr;
}

std::unique_ptr<SocketAddressIn6_t> convertIpv6(const sck::Address& address) {
auto tryConversion = [](SocketAddressIn6_t& recipient, const sck::Address& address) -> bool {
#if !defined(_WIN32)
in6_addr ia;
if (1 == ::inet_pton(AF_INET6, address.getHost().c_str(), &ia)) {
recipient.sin6_addr = ia;
return true;
}
#endif

addrinfo* res, hints = addrinfo{};
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;

int gai_err = ::getaddrinfo(address.getHost().c_str(), NULL, &hints, &res);

#if !defined(_WIN32)
if (gai_err == EAI_SYSTEM) {
return false;
}
#endif
if (gai_err != 0) {
return false;
}

auto ipv6 = reinterpret_cast<sockaddr_in6*>(res->ai_addr);
::freeaddrinfo(res);
recipient.sin6_addr = ipv6->sin6_addr;
return true;
};

if (sck::Family::IP_V6 == address.getFamily()) {
std::unique_ptr<SocketAddressIn6_t> resolved = std::make_unique<SocketAddressIn6_t>();
// set everything to 0 first
::memset(&(*resolved), 0, sizeof(SocketAddressIn6_t));
resolved->sin6_family = AF_INET6;
resolved->sin6_flowinfo = 0;
if (!tryConversion(*resolved, address)) {
return nullptr;
}
resolved->sin6_port = htons(address.getPort());
return resolved;
}
return nullptr;
}

AddressPtr convert(const SocketAddress_t& address) {
// refer to https://stackoverflow.com/questions/11684008/how-do-you-cast-sockaddr-structure-to-a-sockaddr-in-c-networking-sockets-ubu
std::string ip;
std::uint16_t port;
if (AF_INET == address.sa_family) {
// ipv4 address
// inet_ntoa is deprecated, but using inet_ntop for ipv4 address, leads to an ip that has no sense
ip = std::string(::inet_ntoa(reinterpret_cast<const SocketAddressIn_t*>(&address)->sin_addr));
port = ntohs(reinterpret_cast<const SocketAddressIn_t*>(&address)->sin_port);
}
else {
// ipv6 address
char temp[INET6_ADDRSTRLEN]; //this is the longest one
// refer to https://www.gnu.org/software/libc/manual/html_node/Host-Address-Functions.html
::memset(temp, 0, INET6_ADDRSTRLEN);
::inet_ntop(address.sa_family, &address, temp, INET6_ADDRSTRLEN);
ip = std::string(temp, INET6_ADDRSTRLEN);
port = ntohs(reinterpret_cast<const SocketAddressIn6_t*>(&address)->sin6_port);
}
return sck::Address::create(ip, port);
}

Handler::~Handler() {
if(this->opened){
this->close();
}
}

Handler::Handler()
: opened(false)
, socketId(SCK_INVALID_SOCKET) {
#ifdef _WIN32
this->manager = WSAManager::getManager();
#endif
}

Handler::Handler(Socket_t extOpendSocket)
: Handler() {
this->opened = true;
this->socketId = extOpendSocket;
}

void Handler::open(const Protocol& type, const Family& family) {
if(this->opened) return;

auto toIntFamily = [](const Family& family) -> int {
switch (family) {
case sck::Family::IP_V4:
return AF_INET;
case sck::Family::IP_V6:
return AF_INET6;
default:
throw Error("unknown address family type");
}
throw Error("unknown address family type");
};

switch (type) {
case Protocol::TCP:
this->socketId = ::socket(toIntFamily(family), SOCK_STREAM, 0);
if (this->socketId == SCK_INVALID_SOCKET) {
this->close();
throwWithCode("Stream socket could not be created");
}
break;
case Protocol::UDP:
this->socketId = ::socket(toIntFamily(family), SOCK_DGRAM, 0);
if (this->socketId == SCK_INVALID_SOCKET) {
this->close();
throwWithCode("DataGram socket could not be created");
}
default:
throw Error("unknown protocol type");
}

this->opened = true;
}

void Handler::close() {
if (!this->opened) return;
#ifdef _WIN32
shutdown(this->socketId, 2);
closesocket(this->socketId);
#else
::shutdown(this->socketId, SHUT_RDWR);
::close(this->socketId);
#endif
this->opened = false;
this->socketId = SCK_INVALID_SOCKET;
}
}
83 changes: 45 additions & 38 deletions CrossSocket/src/SocketHandler.h → CrossSocket/src/Handler.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
#ifndef _CROSS_SOCKET_SOCKETHANDLER_H_
#define _CROSS_SOCKET_SOCKETHANDLER_H_
/**
* Author: Andrea Casalino
* Created: 01.28.2020
*
* report any bug to andrecasa91@gmail.com.
**/

#ifndef _CROSS_SOCKET_HANDLER_H_
#define _CROSS_SOCKET_HANDLER_H_

#include <Address.h>
#include <SocketConcrete.h>
#include <atomic>
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
@@ -20,14 +29,6 @@
#endif

namespace sck {

/**
* @brief returns the last error code raised by the socket API
*/
int getLastError();

void throwWithCode(const std::string& what);

/**
* socket handle
*/
@@ -61,6 +62,13 @@ namespace sck {
using SocketAddressIn6_t = sockaddr_in6;
#endif

/**
* @brief returns the last error code raised by the socket API
*/
int getLastError();

void throwWithCode(const std::string& what);

/**
* @brief checks the address syntax and in case
* it's valid, creates the socket API representation
@@ -73,63 +81,62 @@ namespace sck {
* of the address
*/
std::unique_ptr<SocketAddressIn6_t> convertIpv6(const sck::Address& address);

/**
* @brief Convert a SocketAddress_t into an Address
*/
AddressPtr convert(const SocketAddress_t& address);

/**
* @brief the integer representing a family type
*/
int castFamily(const sck::Family& family);

/**
* contains the required things to work with the socket API
*/
class SocketHandler {
class Handler {
public:
Handler(const Handler&) = delete;
Handler& operator=(const Handler&) = delete;

/**
* @brief an empty socket is actually created
* only after a call to SocketConnection::open this socket will be activated
* @brief a closed socket is created
*/
SocketHandler();
Handler();

/**
* @brief the handle is transferred into the object to create
* @brief the passed socket should be already opened
*/
SocketHandler(SocketHandler&& o);
Handler(Socket_t extOpendSocket);

virtual ~Handler();

/**
* @brief if the socket was activated, it's shut down and then closed
* @brief internally creates a new socket handler
*/
virtual ~SocketHandler();
void open(const Protocol& type, const Family& family);
/**
* @brief When before calling the destroyer invalidates the socket.
* The socket cannot be used in any way after calling this method
* @brief close and shutdown the current socket handler
*/
void close();
inline bool isOpen() const { return this->opened; };

SocketHandler(const SocketHandler&) = delete;
void operator=(const SocketHandler&) = delete;
inline const Socket_t& getSocketId() const { return this->socketId; }

Socket_t handle;

bool isActive() const;
private:
bool active;
std::atomic_bool opened;
Socket_t socketId;

#ifdef _WIN32
/**
* @brief When the manager is created WSAStartup is called,
* when is destroyed WSACleanup is called
*/
class WSAManagerSingleton {
class WSAManager {
public:
~WSAManagerSingleton();
static std::shared_ptr<WSAManagerSingleton> getManager();
~WSAManager();
static std::shared_ptr<WSAManager> getManager();

private:
WSAManagerSingleton();
static std::shared_ptr<WSAManagerSingleton> managerInstance;
WSAManager();
static std::shared_ptr<WSAManager> managerInstance;
};
std::shared_ptr<WSAManagerSingleton> manager;
std::shared_ptr<WSAManager> manager;
#endif
};

61 changes: 61 additions & 0 deletions CrossSocket/src/MessangerConcrete.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* Author: Andrea Casalino
* Created: 01.28.2020
*
* report any bug to andrecasa91@gmail.com.
**/

#include <MessangerConcrete.h>
#include <Error.h>
#include "Handler.h"

namespace sck {
MessangerConcrete::MessangerConcrete(std::shared_ptr<Handler> messageChannel) {
if(nullptr == messageChannel) {
throw Error("found null channel when building MessangerConcrete");
}
this->messageChannel = messageChannel;
}

bool MessangerConcrete::send(const std::pair<const char*, std::size_t>& message) {
int sentBytes = ::send(this->messageChannel->getSocketId(), message.first, static_cast<int>(message.second), 0);
if (sentBytes == SCK_SOCKET_ERROR) {
sentBytes = 0;
throwWithCode("send failed");
}
return (sentBytes == static_cast<int>(message.second));
}

std::size_t MessangerConcrete::receive(std::pair<char*, std::size_t>& message, const std::chrono::milliseconds& timeout) {
if (timeout.count() != this->actualTimeOut.count()) {
//set new timeout
this->actualTimeOut = timeout;
#ifdef _WIN32
auto tv = DWORD(this->actualTimeOut.count());
if (setsockopt(this->messageChannel->getSocketId(), SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&tv), sizeof(DWORD)) == SOCKET_ERROR) {
#else
struct timeval tv = { 0,0 };
if (this->actualTimeOut.count() >= 1000) {
tv.tv_sec = std::chrono::duration_cast<std::chrono::seconds>(this->actualTimeOut).count();
}
else {
tv.tv_usec = std::chrono::duration_cast<std::chrono::microseconds>(this->actualTimeOut).count();
}
if (::setsockopt(this->messageChannel->getSocketId(), SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&tv), sizeof(struct timeval)) < 0) {
#endif
throwWithCode("can't set timeout");
}
}

int recvBytes = ::recv(this->messageChannel->getSocketId(), message.first, static_cast<int>(message.second), 0);
if (recvBytes == SCK_SOCKET_ERROR) {
recvBytes = 0;
throwWithCode("receive failed");
}
if (recvBytes > message.second) {
// if here, the message received is probably corrupted
recvBytes = 0;
}
return static_cast<std::size_t>(recvBytes);
}
}
72 changes: 11 additions & 61 deletions CrossSocket/src/SocketClient.cpp
Original file line number Diff line number Diff line change
@@ -6,79 +6,29 @@
**/

#include <SocketClient.h>
#include "SocketHandler.h"
#include "Handler.h"

namespace sck {
SocketClient::SocketClient(const sck::Address& remoteAddress)
: Socket()
, remoteAddress(remoteAddress)
, actualTimeOut(std::chrono::milliseconds(0)) {
: SocketConcrete(std::make_shared<Handler>())
, MessangerConcrete(this->SocketConcrete::channel)
, remoteAddress(remoteAddress) {
}

SocketClient::SocketClient(const sck::Address& remoteAddress, std::unique_ptr<SocketHandler> channel)
: Socket(std::move(channel))
, remoteAddress(remoteAddress)
, actualTimeOut(std::chrono::milliseconds(0)) {
SocketClient::SocketClient(const sck::Address& remoteAddress, std::shared_ptr<Handler> channel)
: SocketConcrete(channel)
, MessangerConcrete(this->SocketConcrete::channel)
, remoteAddress(remoteAddress) {
}

const sck::Address& SocketClient::getRemoteAddress() const {
return this->remoteAddress;
}

sck::Family SocketClient::getFamily() {
return this->remoteAddress.getFamily();
}

std::size_t SocketClient::send(const char* buffer, const std::size_t& bufferSize) {
int sentBytes = ::send(this->channel->handle, buffer, static_cast<int>(bufferSize), 0);
if (sentBytes == SCK_SOCKET_ERROR) {
sentBytes = 0;
throwWithCode("send failed");
}
return static_cast<std::size_t>(sentBytes);
}

std::size_t SocketClient::receive(char* buffer, const std::size_t & bufferMaxSize, const std::chrono::milliseconds& timeout) {
if (timeout.count() != this->actualTimeOut.count()) {
//set new timeout
this->actualTimeOut = timeout;
#ifdef _WIN32
auto tv = DWORD(this->actualTimeOut.count());
if (setsockopt(this->channel->handle, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&tv), sizeof(DWORD)) == SOCKET_ERROR) {
#else
struct timeval tv = { 0,0 };
if (this->actualTimeOut.count() >= 1000) {
tv.tv_sec = std::chrono::duration_cast<std::chrono::seconds>(this->actualTimeOut).count();
}
else {
tv.tv_usec = std::chrono::duration_cast<std::chrono::microseconds>(this->actualTimeOut).count();
}
if (::setsockopt(this->channel->handle, SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast<const char*>(&tv), sizeof(struct timeval)) < 0) {
#endif
throwWithCode("can't set timeout");
}
}

int recvBytes = ::recv(this->channel->handle, buffer, static_cast<int>(bufferMaxSize), 0);
if (recvBytes == SCK_SOCKET_ERROR) {
recvBytes = 0;
throwWithCode("receive failed");
}
if (recvBytes > bufferMaxSize) {
// if here, the message received is probably corrupted
recvBytes = 0;
}
return static_cast<std::size_t>(recvBytes);
}

void SocketClient::openConnection() {
void SocketClient::openSpecific() {
if (sck::Family::IP_V4 == this->getFamily()) {
//v4 family
auto addr = convertIpv4(this->remoteAddress);
if (!addr) {
throw std::runtime_error(this->remoteAddress.getHost() + ":" + std::to_string(this->remoteAddress.getPort()) + " is an invalid server address");
}
if (::connect(this->channel->handle, reinterpret_cast<SocketAddress_t*>(&(*addr)), sizeof(SocketAddressIn_t)) == SCK_SOCKET_ERROR) {
if (::connect(this->channel->getSocketId(), reinterpret_cast<SocketAddress_t*>(&(*addr)), sizeof(SocketAddressIn_t)) == SCK_SOCKET_ERROR) {
throwWithCode("Connection can't be established");
}
}
@@ -88,7 +38,7 @@ namespace sck {
if (!addr) {
throw std::runtime_error(this->remoteAddress.getHost() + ":" + std::to_string(this->remoteAddress.getPort()) + " is an invalid server address");
}
if (::connect(this->channel->handle, reinterpret_cast<SocketAddress_t*>(&(*addr)), sizeof(SocketAddressIn6_t)) == SCK_SOCKET_ERROR) {
if (::connect(this->channel->getSocketId(), reinterpret_cast<SocketAddress_t*>(&(*addr)), sizeof(SocketAddressIn6_t)) == SCK_SOCKET_ERROR) {
throwWithCode("Connection can't be established");
}
}
86 changes: 37 additions & 49 deletions CrossSocket/src/Socket.cpp → CrossSocket/src/SocketConcrete.cpp
Original file line number Diff line number Diff line change
@@ -5,8 +5,8 @@
* report any bug to andrecasa91@gmail.com.
**/

#include <Socket.h>
#include "SocketHandler.h"
#include <SocketConcrete.h>
#include "Handler.h"
#include <thread>
#include <condition_variable>

@@ -17,41 +17,32 @@
#endif

namespace sck {
Socket::Socket()
: channel(std::make_unique<SocketHandler>())
, opened(false) {
}

Socket::Socket(std::unique_ptr<SocketHandler> channel)
: channel(std::move(channel))
, opened(false) {
}
SocketConcrete::SocketConcrete(std::shared_ptr<Handler> channel)
: channel(channel) {
}

Socket::~Socket() {
this->close();
}
SocketConcrete::~SocketConcrete() {
if(this->isOpen()) {
this->close();
}
}

void Socket::open(const std::chrono::milliseconds& timeout) {
if (this->opened) {
return;
void SocketConcrete::open(const std::chrono::milliseconds& timeout) {
if (this->isOpen()) {
return;
}
if (!this->channel->isActive()) {
this->channel.reset();
this->channel = std::make_unique<SocketHandler>();
}


std::atomic_bool stopWait(false);
auto openSteps = [this, &stopWait]() {
try {
this->initHandle();
this->openConnection();
this->channel->open(this->getProtocol(), this->getFamily());
this->openSpecific();
}
catch (...) {
this->close();
stopWait = true;
return;
}
this->opened = true;
stopWait = true;
};

@@ -65,28 +56,30 @@ namespace sck {

std::unique_lock<std::mutex> notificationLck(notificationMtx);
notification.wait_for(notificationLck, timeout, [&stopWait](){ return static_cast<bool>(stopWait); });
if(!this->opened) {
if(!this->isOpen()) {
this->close();
this->opened = false;
}
}
}

void Socket::close() {
if (!this->opened) {
return;
}
try {
this->closeConnection();
}
catch (...) {
}
this->opened = false;
}
void SocketConcrete::close() {
if (!this->isOpen()) {
return;
}
try {
this->closeSpecific();
}
catch (...) {
}
}

void SocketConcrete::closeSpecific() {
this->channel->close();
}

void Socket::bindToPort(const std::uint16_t& port) {
void SocketConcrete::bindToPort(const std::uint16_t& port) {
int reusePortOptVal = 1;
::setsockopt(this->channel->handle, SOL_SOCKET, REBIND_OPTION, reinterpret_cast<const
::setsockopt(this->channel->getSocketId(), SOL_SOCKET, REBIND_OPTION, reinterpret_cast<const
#ifdef _WIN32
char* // not sure it would work with void* also in Windows
#else
@@ -106,7 +99,7 @@ namespace sck {
#else
addr.sin_addr.s_addr = ::htonl(INADDR_ANY);
#endif
if (::bind(this->channel->handle, reinterpret_cast<SocketAddress_t*>(&addr), sizeof(SocketAddressIn_t)) == SCK_SOCKET_ERROR) {
if (::bind(this->channel->getSocketId(), reinterpret_cast<SocketAddress_t*>(&addr), sizeof(SocketAddressIn_t)) == SCK_SOCKET_ERROR) {
throwWithCode("can't bind localhost on port: " + std::to_string(port));
}
}
@@ -118,14 +111,9 @@ namespace sck {
addr.sin6_flowinfo = 0;
addr.sin6_addr = IN6ADDR_ANY_INIT; // apparently, there is no such a cross-system define for ipv4 addresses
addr.sin6_port = htons(port);
if (::bind(this->channel->handle, reinterpret_cast<SocketAddress_t*>(&addr), sizeof(SocketAddressIn6_t)) == SCK_SOCKET_ERROR) {
if (::bind(this->channel->getSocketId(), reinterpret_cast<SocketAddress_t*>(&addr), sizeof(SocketAddressIn6_t)) == SCK_SOCKET_ERROR) {
throwWithCode("can't bind localhost on port: " + std::to_string(port));
}

}
}

void Socket::closeConnection() {
this->channel->close();
}
}
}
}
18 changes: 18 additions & 0 deletions CrossSocket/src/SocketDecorator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Author: Andrea Casalino
* Created: 01.28.2020
*
* report any bug to andrecasa91@gmail.com.
**/

#include <SocketDecorator.h>
#include <Error.h>

namespace sck {
SocketDecorator::SocketDecorator(std::unique_ptr<Socket> wrapped) {
if(nullptr == wrapped) {
throw Error("passed null wrapped when building socket decorator");
}
this->wrapped = std::move(wrapped);
}
}
223 changes: 0 additions & 223 deletions CrossSocket/src/SocketHandler.cpp

This file was deleted.

25 changes: 0 additions & 25 deletions CrossSocket/src/SocketServer.cpp

This file was deleted.

35 changes: 0 additions & 35 deletions CrossSocket/src/async/AsyncClient.cpp

This file was deleted.

27 changes: 0 additions & 27 deletions CrossSocket/src/async/AsyncTcpServer.cpp

This file was deleted.

61 changes: 0 additions & 61 deletions CrossSocket/src/async/Service.cpp

This file was deleted.

13 changes: 3 additions & 10 deletions CrossSocket/src/tcp/TcpClient.cpp
Original file line number Diff line number Diff line change
@@ -6,22 +6,15 @@
**/

#include <tcp/TcpClient.h>
#include "../SocketHandler.h"
#include "../Handler.h"

namespace sck::tcp {

TcpClient::TcpClient(const sck::Address& remoteAddress)
: SocketClient(remoteAddress) {
}

TcpClient::TcpClient(const sck::Address& remoteAddress, std::unique_ptr<SocketHandler> channel)
: SocketClient(remoteAddress, std::move(channel)) {
}

void TcpClient::initHandle() {
this->channel->handle = ::socket(castFamily(this->getFamily()), SOCK_STREAM, 0);
if (this->channel->handle == SCK_INVALID_SOCKET) {
throwWithCode("Stream socket could not be created");
}
TcpClient::TcpClient(const sck::Address& remoteAddress, std::shared_ptr<Handler> channel)
: SocketClient(remoteAddress, channel) {
}
}
38 changes: 16 additions & 22 deletions CrossSocket/src/tcp/TcpServer.cpp
Original file line number Diff line number Diff line change
@@ -7,66 +7,60 @@

#include <tcp/TcpServer.h>
#include <tcp/TcpClient.h>
#include "../SocketHandler.h"
#include "../Handler.h"

namespace sck::tcp {

constexpr std::size_t LISTEN_BACKLOG = 50;

class ClientHandler : public TcpClient {
public:
explicit ClientHandler(const sck::Address& remoteAddress, std::unique_ptr<SocketHandler> channel)
: TcpClient(remoteAddress, std::move(channel)) {
this->opened = true;
explicit ClientHandler(const sck::Address& remoteAddress, std::shared_ptr<Handler> channel)
: TcpClient(remoteAddress, channel) {
};

~ClientHandler() override = default;

private:
void openConnection() final {
void openSpecific() final {
throw std::runtime_error("ClientHandler from TcpServer are not re-openable!");
};
};

TcpServer::TcpServer(const std::uint16_t& port, const Family& family)
: SocketServer(port, family) {
: SocketConcrete(std::make_shared<Handler>())
, port(port)
, protocol(family) {
}

std::unique_ptr<SocketClient> TcpServer::acceptClient() {
SocketAddress_t acceptedClientAddress;
std::unique_ptr<SocketHandler> acceptedClientHandler = std::make_unique<SocketHandler>();
#ifdef _WIN32
int acceptedAddressLength
#else
unsigned int acceptedAddressLength
#endif
= sizeof(SocketAddress_t);
// accept: wait for a client to call connect and hit this server and get a pointer to this client.
acceptedClientHandler->handle = ::accept(this->channel->handle, &acceptedClientAddress, &acceptedAddressLength);
if (acceptedClientHandler->handle == SCK_INVALID_SOCKET) {
Socket_t temp = ::accept(this->channel->getSocketId(), &acceptedClientAddress, &acceptedAddressLength);
if (temp == SCK_INVALID_SOCKET) {
throwWithCode("Error: accepting new client");
}
std::shared_ptr<Handler> acceptedClientHandler = std::make_shared<Handler>(temp);

AddressPtr remoteAddress = convert(acceptedClientAddress);
if (nullptr != remoteAddress) {
throw std::runtime_error("accepted client remote address is not resolvable");
}

return std::make_unique<ClientHandler>(*remoteAddress, std::move(acceptedClientHandler));
return std::make_unique<ClientHandler>(*remoteAddress, acceptedClientHandler);
}

void TcpServer::initHandle() {
this->channel->handle = ::socket(castFamily(this->SocketServer::getFamily()), SOCK_STREAM, 0);
if (this->channel->handle == SCK_INVALID_SOCKET) {
throwWithCode("Stream socket could not be created");
}
}

void TcpServer::openConnection() {
this->bindToPort(this->getPort());
void TcpServer::openSpecific() {
this->bindToPort(this->port);
// listen to the port to allow all the following clients acceptance
if (::listen(this->channel->handle, LISTEN_BACKLOG) == SCK_SOCKET_ERROR) {
throwWithCode("Error: listening on port: " + std::to_string(this->getPort()));
if (::listen(this->channel->getSocketId(), LISTEN_BACKLOG) == SCK_SOCKET_ERROR) {
throwWithCode("Error: listening on port: " + std::to_string(this->port));
}
}

}
14 changes: 3 additions & 11 deletions CrossSocket/src/udp/UdpClient.cpp
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
**/

#include <udp/UdpClient.h>
#include "../SocketHandler.h"
#include "../Handler.h"

namespace sck::udp {

@@ -15,16 +15,8 @@ namespace sck::udp {
, port(localPort) {
}

void UdpClient::initHandle() {
this->channel->handle = ::socket(castFamily(this->getFamily()), SOCK_DGRAM, 0);
if (this->channel->handle == SCK_INVALID_SOCKET) {
throwWithCode("DataGram socket could not be created");
}
}

void UdpClient::openConnection() {
void UdpClient::openSpecific() {
this->bindToPort(this->port);
this->SocketClient::openConnection();

this->SocketClient::openSpecific();
}
}
8 changes: 4 additions & 4 deletions CrossSocket/src/udp/UdpServer.cpp
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
**/

#include <udp/UdpServer.h>
#include "../SocketHandler.h"
#include "../Handler.h"
#include <Error.h>

namespace sck::udp {
@@ -22,7 +22,7 @@ namespace sck::udp {
: UdpClient(getInitialAddress(protocol), localPort) {
}

void UdpServer::openConnection() {
void UdpServer::openSpecific() {
this->bindToPort(this->port);

// receive a message from the client, that from now on will beccome the recognized one.
@@ -34,14 +34,14 @@ namespace sck::udp {
unsigned int
#endif
remoteAddrLen = sizeof(SocketAddress_t);
if (::recvfrom(this->channel->handle, &bf, MAX_UDP_RECV_MESSAGE, 0, &remoteAddr, &remoteAddrLen) == SCK_SOCKET_ERROR) {
if (::recvfrom(this->channel->getSocketId(), &bf, MAX_UDP_RECV_MESSAGE, 0, &remoteAddr, &remoteAddrLen) == SCK_SOCKET_ERROR) {
throwWithCode("recvfrom failed while identifying the target");
}
AddressPtr remoteConverted = convert(remoteAddr);
if(nullptr == remoteConverted) {
throw Error(remoteAddr.sa_data, " is an invalid data for udp serer remote address");
}
this->remoteAddress = *remoteConverted;
this->SocketClient::openConnection();
this->SocketClient::openSpecific();
}
}
6 changes: 6 additions & 0 deletions TODO
Original file line number Diff line number Diff line change
@@ -3,3 +3,9 @@ make attribute const when possible
inline getter when possible
togliere cmake script inutili
rimettere typed connections
virtual destroyer
delete copy c'tor in interfacce in cima e gerarchia
remove default d'tor
provare in Windows
remove Socket Server
add explicit a c?tor single input