Skip to content

Commit 5519c28

Browse files
committed
Are used non blocking sockets
1 parent 8975bed commit 5519c28

File tree

10 files changed

+362
-26
lines changed

10 files changed

+362
-26
lines changed

httpserverapp.userprefs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
<Properties>
22
<MonoDevelop.Ide.Workspace ActiveConfiguration="Release" />
3-
<MonoDevelop.Ide.Workbench ActiveDocument="httpserverapp/Main.cpp">
3+
<MonoDevelop.Ide.Workbench ActiveDocument="httpserverapp/Utils.cpp">
44
<Files>
55
<File FileName="httpserverapp/Main.h" Line="1" Column="1" />
6-
<File FileName="httpserverapp/Main.cpp" Line="49" Column="56" />
6+
<File FileName="httpserverapp/Main.cpp" Line="1" Column="1" />
77
<File FileName="httpserverapp/ServerRequest.h" Line="1" Column="1" />
88
<File FileName="httpserverapp/ServerResponse.h" Line="1" Column="1" />
99
<File FileName="httpserverapp/Utils.h" Line="1" Column="1" />
1010
<File FileName="httpserverapp/Test.h" Line="1" Column="1" />
1111
<File FileName="httpserverapp/Test.cpp" Line="1" Column="1" />
1212
<File FileName="httpserverapp/Socket.h" Line="1" Column="1" />
13-
<File FileName="httpserverapp/Utils.cpp" Line="1" Column="1" />
13+
<File FileName="httpserverapp/Utils.cpp" Line="245" Column="3" />
1414
<File FileName="httpserverapp/Socket.cpp" Line="1" Column="1" />
1515
<File FileName="httpserverapp/System.h" Line="1" Column="1" />
1616
<File FileName="httpserverapp/RawData.h" Line="1" Column="1" />

httpserverapp/Main.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ DLLEXPORT int application_call(HttpServer::server_request *request, HttpServer::
4646

4747
if (file)
4848
{
49-
// proc_response.headers["Connection"] = "Keep-Alive";
49+
proc_response.headers["Connection"] = "keep-alive";
5050
proc_response.headers["X-Sendfile"] = absolute_path;
5151
}
5252
else

httpserverapp/Socket.cpp

100755100644
Lines changed: 148 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,7 @@ namespace HttpServer
3737
socket_handle = handle;
3838
}
3939

40-
Socket::~Socket()
41-
{
42-
43-
}
44-
45-
int Socket::open()
40+
System::native_socket_type Socket::open()
4641
{
4742
close();
4843

@@ -118,6 +113,18 @@ namespace HttpServer
118113
return -1;
119114
}
120115

116+
bool Socket::nonblock(bool isNonBlock)
117+
{
118+
#ifdef WIN32
119+
unsigned long value = isNonBlock;
120+
return 0 == ioctlsocket(socket_handle, FIONBIO, &value);
121+
#elif POSIX
122+
return -1 != fcntl(socket_handle, F_SETFL, isNonBlock ? O_NONBLOCK : O_SYNC);
123+
#else
124+
#error "Undefine platform"
125+
#endif
126+
}
127+
121128
size_t Socket::recv(std::vector<std::string::value_type> &buf) const
122129
{
123130
#ifdef WIN32
@@ -129,6 +136,47 @@ namespace HttpServer
129136
#endif
130137
}
131138

139+
size_t Socket::nonblock_recv(std::vector<std::string::value_type> &buf, const std::chrono::milliseconds &timeWait) const
140+
{
141+
#ifdef WIN32
142+
fd_set readset;
143+
FD_ZERO(&readset);
144+
FD_SET(socket_handle, &readset);
145+
146+
long seconds = timeWait.count() / 1000;
147+
timeval timeout {seconds, (timeWait.count() - seconds * 1000) * 1000};
148+
149+
if (0 < select(socket_handle + 1, &readset, nullptr, nullptr, &timeout) )
150+
{
151+
if (FD_ISSET(socket_handle, &readset) )
152+
{
153+
return ::recv(socket_handle, buf.data(), buf.size(), 0);
154+
}
155+
}
156+
157+
return std::numeric_limits<size_t>::max();
158+
#elif POSIX
159+
fd_set readset;
160+
FD_ZERO(&readset);
161+
FD_SET(socket_handle, &readset);
162+
163+
long seconds = timeWait.count() / 1000;
164+
timeval timeout {seconds, (timeWait.count() - seconds * 1000) * 1000};
165+
166+
if (0 < select(socket_handle + 1, &readset, nullptr, nullptr, &timeout) )
167+
{
168+
if (FD_ISSET(socket_handle, &readset) )
169+
{
170+
return ::recv(socket_handle, buf.data(), buf.size(), MSG_NOSIGNAL);
171+
}
172+
}
173+
174+
return std::numeric_limits<size_t>::max();
175+
#else
176+
#error "Undefine platform"
177+
#endif
178+
}
179+
132180
size_t Socket::send(const std::string &buf) const
133181
{
134182
#ifdef WIN32
@@ -140,9 +188,102 @@ namespace HttpServer
140188
#endif
141189
}
142190

191+
size_t Socket::send(const std::vector<std::string::value_type> &buf, const size_t length) const
192+
{
193+
#ifdef WIN32
194+
return ::send(socket_handle, buf.data(), length, 0);
195+
#elif POSIX
196+
return ::send(socket_handle, buf.data(), length, MSG_WAITALL | MSG_NOSIGNAL);
197+
#else
198+
#error "Undefine platform"
199+
#endif
200+
}
201+
202+
size_t Socket::nonblock_send(const std::string &buf, const std::chrono::milliseconds &timeWait) const
203+
{
204+
#ifdef WIN32
205+
fd_set writeset;
206+
FD_ZERO(&writeset);
207+
FD_SET(socket_handle, &writeset);
208+
209+
long seconds = timeWait.count() / 1000;
210+
timeval timeout {seconds, (timeWait.count() - seconds * 1000) * 1000};
211+
212+
if (0 < select(socket_handle + 1, nullptr, &writeset, nullptr, &timeout) )
213+
{
214+
if (FD_ISSET(socket_handle, &writeset) )
215+
{
216+
return ::send(socket_handle, buf.data(), buf.length(), 0);
217+
}
218+
}
219+
220+
return std::numeric_limits<size_t>::max();
221+
#elif POSIX
222+
fd_set writeset;
223+
FD_ZERO(&writeset);
224+
FD_SET(socket_handle, &writeset);
225+
226+
long seconds = timeWait.count() / 1000;
227+
timeval timeout {seconds, (timeWait.count() - seconds * 1000) * 1000};
228+
229+
if (0 < select(socket_handle + 1, nullptr, &writeset, nullptr, &timeout) )
230+
{
231+
if (FD_ISSET(socket_handle, &writeset) )
232+
{
233+
return ::send(socket_handle, buf.data(), buf.length(), MSG_NOSIGNAL);
234+
}
235+
}
236+
237+
return std::numeric_limits<size_t>::max();
238+
#else
239+
#error "Undefine platform"
240+
#endif
241+
}
242+
243+
size_t Socket::nonblock_send(const std::vector<std::string::value_type> &buf, const size_t length, const std::chrono::milliseconds &timeWait) const
244+
{
245+
#ifdef WIN32
246+
fd_set writeset;
247+
FD_ZERO(&writeset);
248+
FD_SET(socket_handle, &writeset);
249+
250+
long seconds = timeWait.count() / 1000;
251+
timeval timeout {seconds, (timeWait.count() - seconds * 1000) * 1000};
252+
253+
if (0 < select(socket_handle + 1, nullptr, &writeset, nullptr, &timeout) )
254+
{
255+
if (FD_ISSET(socket_handle, &writeset) )
256+
{
257+
return ::send(socket_handle, buf.data(), length, 0);
258+
}
259+
}
260+
261+
return std::numeric_limits<size_t>::max();
262+
#elif POSIX
263+
fd_set writeset;
264+
FD_ZERO(&writeset);
265+
FD_SET(socket_handle, &writeset);
266+
267+
long seconds = timeWait.count() / 1000;
268+
timeval timeout {seconds, (timeWait.count() - seconds * 1000) * 1000};
269+
270+
if (0 < select(socket_handle + 1, nullptr, &writeset, nullptr, &timeout) )
271+
{
272+
if (FD_ISSET(socket_handle, &writeset) )
273+
{
274+
return ::send(socket_handle, buf.data(), length, MSG_WAITALL | MSG_NOSIGNAL);
275+
}
276+
}
277+
278+
return std::numeric_limits<size_t>::max();
279+
#else
280+
#error "Undefine platform"
281+
#endif
282+
}
283+
143284
Socket &Socket::operator=(const Socket s)
144285
{
145286
socket_handle = s.socket_handle;
146287
return *this;
147288
}
148-
};
289+
};

httpserverapp/Socket.h

100755100644
Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@
33
#ifdef WIN32
44
#include <WinSock2.h>
55
#pragma comment(lib, "ws2_32.lib")
6+
#undef max
67
#elif POSIX
78
#include <sys/types.h>
89
#include <sys/socket.h>
910
#include <netinet/in.h>
1011
#include <unistd.h>
12+
#include <fcntl.h>
1113
#else
1214
#error "Undefine platform"
1315
#endif
@@ -19,6 +21,7 @@
1921

2022
#include <vector>
2123
#include <string>
24+
#include <chrono>
2225

2326
namespace HttpServer
2427
{
@@ -34,9 +37,9 @@ namespace HttpServer
3437
public:
3538
Socket();
3639
Socket(const System::native_socket_type);
37-
~Socket();
40+
~Socket() = default;
3841

39-
int open();
42+
System::native_socket_type open();
4043
int close();
4144

4245
inline bool is_open() const
@@ -48,8 +51,17 @@ namespace HttpServer
4851
int listen() const;
4952
Socket accept() const;
5053
int shutdown() const;
54+
55+
bool nonblock(bool = true);
56+
5157
size_t recv(std::vector<std::string::value_type> &) const;
58+
size_t nonblock_recv(std::vector<std::string::value_type> &, const std::chrono::milliseconds &) const;
59+
5260
size_t send(const std::string &) const;
61+
size_t send(const std::vector<std::string::value_type> &, const size_t) const;
62+
63+
size_t nonblock_send(const std::string &, const std::chrono::milliseconds &) const;
64+
size_t nonblock_send(const std::vector<std::string::value_type> &, const size_t, const std::chrono::milliseconds &) const;
5365

5466
inline System::native_socket_type get_handle() const
5567
{

httpserverapp/System.cpp

Lines changed: 74 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ namespace System
77
struct EnumData
88
{
99
native_processid_type process_id;
10-
HWND hWnd;
10+
::HWND hWnd;
1111
};
1212

13-
BOOL WINAPI EnumProc(HWND hWnd, LPARAM lParam)
13+
BOOL WINAPI EnumProc(::HWND hWnd, ::LPARAM lParam)
1414
{
1515
EnumData &ed = *reinterpret_cast<EnumData *>(lParam);
1616

1717
native_processid_type process_id = 0;
1818

19-
GetWindowThreadProcessId(hWnd, &process_id);
19+
::GetWindowThreadProcessId(hWnd, &process_id);
2020

2121
if (process_id == ed.process_id)
2222
{
@@ -34,14 +34,82 @@ namespace System
3434
#ifdef WIN32
3535
EnumData ed = {pid, nullptr};
3636

37-
if (0 == EnumWindows(EnumProc, reinterpret_cast<LPARAM>(&ed) ) )
37+
if (0 == ::EnumWindows(EnumProc, reinterpret_cast<LPARAM>(&ed) ) )
3838
{
3939
return false;
4040
}
4141

42-
return 0 != PostMessage(ed.hWnd, signal, 0, 0);
42+
return 0 != ::PostMessage(ed.hWnd, signal, 0, 0);
4343
#elif POSIX
44-
return 0 == kill(pid, signal);
44+
return 0 == ::kill(pid, signal);
45+
#else
46+
#error "Undefine platform"
47+
#endif
48+
}
49+
50+
bool getFileSizeAndTimeGmt(const std::string &filePath, size_t *fileSize, time_t *fileTime)
51+
{
52+
#ifdef WIN32
53+
::HANDLE hFile = ::CreateFile(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
54+
55+
if (INVALID_HANDLE_VALUE == hFile)
56+
{
57+
return false;
58+
}
59+
60+
if (false == ::GetFileSizeEx(hFile, reinterpret_cast<PLARGE_INTEGER>(fileSize) ) )
61+
{
62+
return false;
63+
}
64+
65+
::FILETIME ftWrite;
66+
67+
::BOOL result = ::GetFileTime(hFile, nullptr, nullptr, &ftWrite);
68+
69+
::CloseHandle(hFile);
70+
71+
if (false == result)
72+
{
73+
return false;
74+
}
75+
76+
::SYSTEMTIME stUtc;
77+
78+
::FileTimeToSystemTime(&ftWrite, &stUtc);
79+
80+
struct ::tm tm_time {
81+
stUtc.wSecond,
82+
stUtc.wMinute,
83+
stUtc.wHour,
84+
stUtc.wDay,
85+
stUtc.wMonth - 1,
86+
stUtc.wYear - 1900,
87+
0,
88+
0,
89+
0
90+
};
91+
92+
*fileTime = ::mktime(&tm_time);
93+
94+
return true;
95+
#elif POSIX
96+
struct ::tm *clock;
97+
struct ::stat attrib;
98+
99+
if (-1 == ::stat(filePath.c_str(), &attrib) )
100+
{
101+
return false;
102+
}
103+
104+
*fileSize = attrib.st_size;
105+
106+
// *fileTime = attrib.st_mtime;
107+
108+
clock = ::gmtime(&(attrib.st_mtime) );
109+
110+
*fileTime = ::mktime(clock);
111+
112+
return true;
45113
#else
46114
#error "Undefine platform"
47115
#endif

0 commit comments

Comments
 (0)