Skip to content

Commit c1cca2d

Browse files
committed
Added missing stuff.
1 parent a821465 commit c1cca2d

17 files changed

+463
-240
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,5 @@ Socket/Socket.vcxproj
1919
Socket/Socket.vcxproj.filters
2020
SocketTest/SocketTest.vcxproj
2121
SocketTest/SocketTest.vcxproj.filters
22+
SocketTest/SocketTest.vcxproj.user
23+
SocketTest/tcp_test_conf.ini

README.md

Lines changed: 34 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44

55
## About
66
This is a simple TCP server/client for C++. Under Windows, it wraps WinSock and under Linux it wraps
7-
the related socket API (BSD compatible).
8-
It is meant to be a portable and easy-to-use API to create a TCP server or client.
7+
the related socket API (BSD compatible). It wraps also OpenSSL to create secure client/server sockets.
98

10-
Upcoming features : creating secure sockets with OpenSSL and using the sockets in an async way.
9+
It is meant to be a portable and easy-to-use API to create a TCP server or client with or without SSL/TLS
10+
support.
11+
12+
Upcoming features : using the sockets in an async way and proxy support.
1113

1214
Compilation has been tested with:
1315
- GCC 5.4.0 (GNU/Linux Ubuntu 16.04 LTS)
@@ -59,17 +61,37 @@ cmake . -DCMAKE_BUILD_TYPE=Debug # or Release
5961
make
6062
```
6163

62-
To run it :
64+
To run it, you must indicate the path of the INI conf file (see the section below)
6365
```Shell
64-
./bin/[BUILD_TYPE]/test_socket
66+
./bin/[BUILD_TYPE]/test_socket /path_to_your_ini_file/conf.ini
6567
```
6668

69+
Compile both the library and test program with the macro OPENSSL to use the SSL/TLS secured classes.
70+
6771
## Run Unit Tests
6872

69-
You can generate an XML file of test results by adding this argument when calling the test program
73+
[simpleini](https://github.com/brofield/simpleini) is used to gather unit tests parameters from
74+
an INI configuration file. You need to fill that file with some parameters.
75+
You can also disable some tests (HTTP proxy for instance) and indicate
76+
parameters only for the enabled tests. A template of the INI file already exists under TestHTTP/
77+
78+
e.g. to enable SSL/TLS tests :
79+
80+
```ini
81+
[tests]
82+
tcp-ssl=yes
83+
84+
[tcp-ssl]
85+
server_port=4242
86+
ca_file=CAfile.pem
87+
ssl_cert_file=site.cert
88+
ssl_key_file=privkey.pem
89+
```
90+
91+
You can also generate an XML file of test results by adding this argument when calling the test program
7092

7193
```Shell
72-
./bin/[BUILD_TYPE]/test_socket --gtest_output="xml:./TestSocket.xml"
94+
./bin/[BUILD_TYPE]/test_socket /path_to_your_ini_file/conf.ini --gtest_output="xml:./TestSocket.xml"
7395
```
7496

7597
## Memory Leak Check
@@ -80,14 +102,18 @@ You can download it here: https://vld.codeplex.com/
80102
To perform a leak check with the Linux build, you can do so :
81103

82104
```Shell
83-
valgrind --leak-check=full ./bin/Debug/test_socket
105+
valgrind --leak-check=full ./bin/Debug/test_socket /path_to_ini_file/conf.ini
84106
```
85107

86108
## Code Coverage
87109

88110
The code coverage build doesn't use the static library but compiles and uses directly the
89111
socket API in the test program.
90112

113+
First of all, in TestHTTP/CMakeLists.txt, find and repalce :
114+
```
115+
"/home/amzoughi/Test/http_github.ini"
116+
```
91117
by the location of your ini file and launch the code coverage :
92118

93119
```Shell

Socket/SecureSocket.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ std::mutex ASecureSocket::s_mtxSecureCount;
2424
* @param eSSLVersion - SSL/TLS protocol version
2525
*
2626
*/
27-
ASecureSocket::ASecureSocket(const LogFnCallback& oLogger, const OpenSSLProtocol eSSLVersion) :
28-
ASocket(oLogger),
27+
ASecureSocket::ASecureSocket(const LogFnCallback& oLogger,
28+
const OpenSSLProtocol eSSLVersion,
29+
const SettingsFlag eSettings /*= ALL_FLAGS*/) :
30+
ASocket(oLogger, eSettings),
2931
m_eOpenSSLProtocol(eSSLVersion)
3032
{
3133
s_mtxSecureCount.lock();

Socket/SecureSocket.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ class ASecureSocket : public ASocket
5151
/* Please provide your logger thread-safe routine, otherwise, you can turn off
5252
* error log messages printing by not using the flag ALL_FLAGS or ENABLE_LOG */
5353
explicit ASecureSocket(const LogFnCallback& oLogger,
54-
const OpenSSLProtocol eSSLVersion = OpenSSLProtocol::SSL_V23);
54+
const OpenSSLProtocol eSSLVersion = OpenSSLProtocol::SSL_V23,
55+
const SettingsFlag eSettings = ALL_FLAGS);
5556
virtual ~ASecureSocket() = 0;
5657

5758
inline static int GetSSLSocketCount() { return s_iSecureSocketCount; }

Socket/Socket.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ WSADATA ASocket::s_wsaData;
2020
* @param Logger - a callabck to a logger function void(const std::string&)
2121
*
2222
*/
23-
ASocket::ASocket(const LogFnCallback& oLogger) :
24-
m_oLog(oLogger)
23+
ASocket::ASocket(const LogFnCallback& oLogger,
24+
const SettingsFlag eSettings /*= ALL_FLAGS*/) :
25+
m_oLog(oLogger),
26+
m_eSettingsFlags(eSettings)
2527
{
2628
s_mtxCount.lock();
2729
if (s_iSocketCount++ == 0)
@@ -33,7 +35,8 @@ ASocket::ASocket(const LogFnCallback& oLogger) :
3335
// MAKEWORD(2,2) version 2.2 of Winsock
3436
if (iWinSockInitResult != 0)
3537
{
36-
m_oLog(StringFormat("[TCPClient][Error] WSAStartup failed : %d", iWinSockInitResult));
38+
if (m_eSettingsFlags & ENABLE_LOG)
39+
m_oLog(StringFormat("[TCPClient][Error] WSAStartup failed : %d", iWinSockInitResult));
3740
}
3841
#endif
3942
}

Socket/Socket.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,8 @@ class ASocket
6262

6363
/* Please provide your logger thread-safe routine, otherwise, you can turn off
6464
* error log messages printing by not using the flag ALL_FLAGS or ENABLE_LOG */
65-
explicit ASocket(const LogFnCallback& oLogger);
65+
explicit ASocket(const LogFnCallback& oLogger,
66+
const SettingsFlag eSettings = ALL_FLAGS);
6667
virtual ~ASocket() = 0;
6768

6869
inline static int GetSocketCount() { return s_iSocketCount; }
@@ -74,6 +75,8 @@ class ASocket
7475
// Log printer callback
7576
/*mutable*/const LogFnCallback m_oLog;
7677

78+
SettingsFlag m_eSettingsFlags;
79+
7780
#ifdef WINDOWS
7881
static WSADATA s_wsaData;
7982
#endif

Socket/TCPClient.cpp

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66

77
#include "TCPClient.h"
88

9-
CTCPClient::CTCPClient(const LogFnCallback oLogger) :
10-
ASocket(oLogger),
9+
CTCPClient::CTCPClient(const LogFnCallback oLogger,
10+
const SettingsFlag eSettings /*= ALL_FLAGS*/) :
11+
ASocket(oLogger, eSettings),
1112
m_eStatus(DISCONNECTED),
1213
#ifdef WINDOWS
1314
m_ConnectSocket(INVALID_SOCKET),
@@ -27,7 +28,8 @@ bool CTCPClient::Connect(const std::string& strServer, const std::string& strPor
2728
if (m_eStatus == CONNECTED)
2829
{
2930
Disconnect();
30-
m_oLog("[TCPClient][Warning] Opening a new connexion. The last one was automatically closed.");
31+
if (m_eSettingsFlags & ENABLE_LOG)
32+
m_oLog("[TCPClient][Warning] Opening a new connexion. The last one was automatically closed.");
3133
}
3234

3335
#ifdef WINDOWS
@@ -43,7 +45,8 @@ bool CTCPClient::Connect(const std::string& strServer, const std::string& strPor
4345
int iResult = getaddrinfo(strServer.c_str(), strPort.c_str(), &m_HintsAddrInfo, &m_pResultAddrInfo);
4446
if (iResult != 0)
4547
{
46-
m_oLog(StringFormat("[TCPClient][Error] getaddrinfo failed : %d", iResult));
48+
if (m_eSettingsFlags & ENABLE_LOG)
49+
m_oLog(StringFormat("[TCPClient][Error] getaddrinfo failed : %d", iResult));
4750

4851
if (m_pResultAddrInfo != nullptr)
4952
{
@@ -61,7 +64,9 @@ bool CTCPClient::Connect(const std::string& strServer, const std::string& strPor
6164

6265
if (m_ConnectSocket == INVALID_SOCKET)
6366
{
64-
m_oLog(StringFormat("[TCPClient][Error] socket failed : %d", WSAGetLastError()));
67+
if (m_eSettingsFlags & ENABLE_LOG)
68+
m_oLog(StringFormat("[TCPClient][Error] socket failed : %d", WSAGetLastError()));
69+
6570
closesocket(m_ConnectSocket);
6671
freeaddrinfo(m_pResultAddrInfo);
6772
m_pResultAddrInfo = nullptr;
@@ -100,7 +105,9 @@ bool CTCPClient::Connect(const std::string& strServer, const std::string& strPor
100105

101106
// retry mechanism
102107
//if (uRetry < m_uRetryCount)
103-
//m_oLog(StringFormat("[TCPClient][Error] connect retry %u after %u second(s)", m_uRetryCount + 1, m_uRetryPeriod));
108+
//if (m_eSettingsFlags & ENABLE_LOG)
109+
/*m_oLog(StringFormat("[TCPClient][Error] connect retry %u after %u second(s)",
110+
m_uRetryCount + 1, m_uRetryPeriod));*/
104111

105112
//if (m_uRetryPeriod > 0)
106113
//{
@@ -117,22 +124,27 @@ bool CTCPClient::Connect(const std::string& strServer, const std::string& strPor
117124
m_eStatus = CONNECTED;
118125
return true;
119126
}
120-
m_oLog(StringFormat("[TCPClient][Error] Unable to connect to server : %d", WSAGetLastError()));
127+
if (m_eSettingsFlags & ENABLE_LOG)
128+
m_oLog(StringFormat("[TCPClient][Error] Unable to connect to server : %d", WSAGetLastError()));
121129

122130
#else
123131
// socket creation
124132
m_ConnectSocket = socket(AF_INET, SOCK_STREAM, 0);
125133
if (m_ConnectSocket < 0)
126134
{
127-
m_oLog(StringFormat("[TCPClient][Error] opening socket: %s", strerror(errno)));
135+
if (m_eSettingsFlags & ENABLE_LOG)
136+
m_oLog(StringFormat("[TCPClient][Error] opening socket: %s", strerror(errno)));
137+
128138
return false;
129139
}
130140

131141
int iPort = atoi(strPort.c_str());
132142
m_pServer = gethostbyname(strServer.c_str());
133143
if (m_pServer == nullptr)
134144
{
135-
m_oLog("[TCPClient][Error] no such host.");
145+
if (m_eSettingsFlags & ENABLE_LOG)
146+
m_oLog("[TCPClient][Error] no such host.");
147+
136148
return false;
137149
}
138150

@@ -158,7 +170,8 @@ bool CTCPClient::Connect(const std::string& strServer, const std::string& strPor
158170
m_eStatus = CONNECTED;
159171
return true;
160172
}
161-
m_oLog(StringFormat("[TCPClient][Error] connecting : %s", strerror(errno)));
173+
if (m_eSettingsFlags & ENABLE_LOG)
174+
m_oLog(StringFormat("[TCPClient][Error] connecting : %s", strerror(errno)));
162175
#endif
163176

164177
return false;
@@ -168,7 +181,9 @@ bool CTCPClient::Send(const char* pData, const size_t uSize) const
168181
{
169182
if (m_eStatus != CONNECTED)
170183
{
171-
m_oLog("[TCPClient][Error] send failed : not connected to a server.");
184+
if (m_eSettingsFlags & ENABLE_LOG)
185+
m_oLog("[TCPClient][Error] send failed : not connected to a server.");
186+
172187
return false;
173188
}
174189

@@ -177,15 +192,19 @@ bool CTCPClient::Send(const char* pData, const size_t uSize) const
177192
iResult = send(m_ConnectSocket, pData, uSize, 0);
178193
if (iResult == SOCKET_ERROR)
179194
{
180-
m_oLog(StringFormat("[TCPClient][Error] send failed : %d", WSAGetLastError()));
195+
if (m_eSettingsFlags & ENABLE_LOG)
196+
m_oLog(StringFormat("[TCPClient][Error] send failed : %d", WSAGetLastError()));
181197
//Disconnect();
198+
182199
return false;
183200
}
184201
#else
185202
iResult = write(m_ConnectSocket, pData, uSize);
186203
if (iResult < 0)
187204
{
188-
m_oLog(StringFormat("[TCPClient][Error] writing to socket : %s", strerror(errno)));
205+
if (m_eSettingsFlags & ENABLE_LOG)
206+
m_oLog(StringFormat("[TCPClient][Error] writing to socket : %s", strerror(errno)));
207+
189208
return false;
190209
}
191210
#endif
@@ -211,7 +230,9 @@ int CTCPClient::Receive(char* pData, const size_t uSize) const
211230
{
212231
if (m_eStatus != CONNECTED)
213232
{
214-
m_oLog("[TCPClient][Error] recv failed : not connected to a server.");
233+
if (m_eSettingsFlags & ENABLE_LOG)
234+
m_oLog("[TCPClient][Error] recv failed : not connected to a server.");
235+
215236
return -1;
216237
}
217238

@@ -221,14 +242,16 @@ int CTCPClient::Receive(char* pData, const size_t uSize) const
221242
iBytesRcvd = recv(m_ConnectSocket, pData, uSize, 0);
222243
if (iBytesRcvd < 0)
223244
{
224-
m_oLog(StringFormat("[TCPClient][Error] recv failed : %d", WSAGetLastError()));
245+
if (m_eSettingsFlags & ENABLE_LOG)
246+
m_oLog(StringFormat("[TCPClient][Error] recv failed : %d", WSAGetLastError()));
225247
}
226248
#else
227249
//bzero(pData, uSize);
228250
iBytesRcvd = read(m_ConnectSocket, pData, uSize);
229251
if (iBytesRcvd < 0)
230252
{
231-
m_oLog(StringFormat("[TCPClient][Error] reading from socket : %s", strerror(errno)));
253+
if (m_eSettingsFlags & ENABLE_LOG)
254+
m_oLog(StringFormat("[TCPClient][Error] reading from socket : %s", strerror(errno)));
232255
}
233256
#endif
234257

@@ -247,7 +270,9 @@ bool CTCPClient::Disconnect()
247270
int iResult = shutdown(m_ConnectSocket, SD_SEND);
248271
if (iResult == SOCKET_ERROR)
249272
{
250-
m_oLog(StringFormat("[TCPClient][Error] shutdown failed : %d", WSAGetLastError()));
273+
if (m_eSettingsFlags & ENABLE_LOG)
274+
m_oLog(StringFormat("[TCPClient][Error] shutdown failed : %d", WSAGetLastError()));
275+
251276
return false;
252277
}
253278
closesocket(m_ConnectSocket);

Socket/TCPClient.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class CTCPClient : public ASocket
2929
friend class CTCPSSLClient;
3030

3131
public:
32-
explicit CTCPClient(const LogFnCallback oLogger);
32+
explicit CTCPClient(const LogFnCallback oLogger, const SettingsFlag eSettings = ALL_FLAGS);
3333
~CTCPClient() override;
3434

3535
// copy constructor and assignment operator are disabled

0 commit comments

Comments
 (0)