ReactOS 0.4.15-dev-7674-gc0b4db1
socket.cpp
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS HTTP Daemon
4 * FILE: socket.cpp
5 * PURPOSE: Socket classes
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * REVISIONS:
8 * CSH 01/09/2000 Created
9 */
10#include <socket.h>
11#include <string.h>
12#include <error.h>
13#include <iterator.h>
14
15// ***************************** CSocket *****************************
16
17// Default constructor
19{
20 Active = FALSE;
22 Events = 0;
24
25 // INET address family
27
28 // Any address will do
30
31 // Convert to network ordering
33}
34
35// Default destructor
37{
38}
39
40// Return winsock socket handle
42{
43 return Socket;
44}
45
46// Set winsock socket handle
48{
49 Socket = socket;
50}
51
52
53// Return socket address
55{
56 return SockAddrIn;
57}
58
59// Set socket address
61{
62 SockAddrIn = sockaddrin;
63}
64
65// Associate winsock events with socket
67{
68 if (Event == WSA_INVALID_EVENT) {
69 // Create socket event
72 throw ESocketOpen(TS("Unable to create event."));
73 }
74
75 if (lEvents != Events) {
76 // Associate network events with socket
77 if (WSAEventSelect(Socket, Event, lEvents) == SOCKET_ERROR)
78 throw ESocketOpen(TS("Unable to select socket events."));
79 Events = lEvents;
80 }
81}
82
83// Return associated winsock events
85{
86 return Events;
87}
88
89// Open socket
91{
92}
93
94// Close socket
96{
97}
98
99
100// *********************** CServerClientSocket ***********************
101
102// Constructor with serversocket as parameter
104{
105 ServerSocket = lpServerSocket;
106}
107
108// Transmit data to socket
110{
111 return send(Socket, lpsBuffer, nLength, 0);
112}
113
114// Send a string to socket
116{
117 static CHAR crlf[3] = {0x0D, 0x0A, 0x00};
118 INT nCount;
119
120 nCount = Transmit(lpsText, strlen(lpsText));
121 nCount += Transmit(crlf, strlen(crlf));
122 return nCount;
123}
124
125// Receive data from socket
127{
128 return recv(Socket, lpsBuffer, nLength, 0);
129}
130
131// Process winsock messages if any
133{
134 UINT nStatus;
135 WSANETWORKEVENTS NetworkEvents;
136
137 nStatus = WSAWaitForMultipleEvents(1, &Event, FALSE, 0, FALSE);
138 if ((nStatus == 0) && (WSAEnumNetworkEvents(Socket, Event, &NetworkEvents) != SOCKET_ERROR)) {
139 if ((NetworkEvents.lNetworkEvents & FD_READ) != 0) {
140 OnRead();
141 }
142 if ((NetworkEvents.lNetworkEvents & FD_CLOSE) != 0) {
143 OnClose();
144 }
145 }
146}
147
148// Return server socket that own this socket
150{
151 return ServerSocket;
152}
153
154
155// *********************** CServerClientThread ***********************
156
158{
159 ClientSocket = lpSocket;
160}
161
163{
165}
166
167
168// ************************** CServerSocket **************************
169
170// Default constructor
172{
173}
174
175// Default destructor
177{
178 if (Active)
179 Close();
180}
181
182// Open server socket so clients can connect
184{
185 assert(!Active);
186
187 // Convert to network ordering
189
190 if (Socket == INVALID_SOCKET) {
191 // Create socket
193 if (Socket == INVALID_SOCKET)
194 throw ESocketOpen(TS("Unable to allocate a socket."));
195 }
196
197 // Associate an address with server socket
198 if (bind(Socket, (struct sockaddr FAR *) &SockAddrIn, sizeof(SockAddrIn)) == SOCKET_ERROR)
199 throw ESocketOpen(TS("Unable to associate address with socket."));
200
201 // Listen for incoming connections
203 throw ESocketOpen(TS("Unable to listen on socket."));
204
205 // Associate network events with socket
207
208 Active = TRUE;
209}
210
211// Close server socket and all current connections
213{
214 assert(Active);
215
216 if (Event != WSA_INVALID_EVENT) {
217 // Tell winsock not to notify us about any events
219 throw ESocketClose(TS("Unable to select socket events."));
220
221 if (!WSACloseEvent(Event))
222 throw ESocketClose(TS("Unable to close socket event."));
224 }
225
227
228 // Terminate and free all client threads
229 for (i->First(); !i->IsDone(); i->Next()) {
230 //i->CurrentItem()->Terminate();
231 delete i->CurrentItem();
232 }
233 delete i;
234 Connections.RemoveAll();
235
238
239 Active = FALSE;
240}
241
242// Set port number to listen on
244{
245 assert(!Active);
246
247 Port = nPort;
248}
249
250// Process messages from winsock if any
252{
253 UINT nStatus;
254 INT nAddrLen;
255 SOCKET ClientSocket;
257 WSANETWORKEVENTS NetworkEvents;
258 LPCServerClientSocket lpClient;
259 LPCServerClientThread lpThread;
260
261 nStatus = WSAWaitForMultipleEvents(1, &Event, FALSE, 0, FALSE);
262 if ((nStatus == 0) && (WSAEnumNetworkEvents(Socket, Event, &NetworkEvents) != SOCKET_ERROR)) {
263 if ((NetworkEvents.lNetworkEvents & FD_ACCEPT) != 0) {
264 lpClient = OnGetSocket(this);
265 nAddrLen = sizeof(SockAddrIn);
266 ClientSocket = accept(Socket, (SOCKADDR *) &SockAddrIn, &nAddrLen);
267 if (ClientSocket != INVALID_SOCKET) {
268 // Set socket handle
269 lpClient->SetSocket(ClientSocket);
270 // Set socket address
271 lpClient->SetSockAddrIn(SockAddrIn);
272 // Set winsock events
273 lpClient->SetEvents(FD_READ | FD_CLOSE);
274 // Create client connection thread
275 lpThread = OnGetThread(lpClient);
276 // Add client thread to connection list
277 InsertClient(lpThread);
278 // Call OnAccept event handler
279 OnAccept(lpThread);
280 } else {
281 delete lpClient;
282 lpClient = NULL;
283 throw ESocketOpen(TS("No more sockets available."));
284 }
285 }
286 /*if ((NetworkEvents.lNetworkEvents & FD_CONNECT) != 0) {
287 }
288 if ((NetworkEvents.lNetworkEvents & FD_CLOSE) != 0) {
289 }*/
290 }
291}
292
293// Insert client into connection list
295{
296 Connections.Insert(lpClient);
297}
298
299// Remove client from connection list
301{
302 Connections.Remove(lpClient);
303}
304
305// OnGetSocket event handler
307{
308 return NULL;
309}
310
311// OnGetThread event handler
313{
314 return NULL;
315}
316
317
318// Initialize WinSock DLL
320{
321 WORD wVersionRequested;
322 WSADATA wsaData;
323
324 wVersionRequested = MAKEWORD(2, 0);
325
326 if (WSAStartup(wVersionRequested, &wsaData) != 0)
327 // Return FALSE as we couldn't find a usable WinSock DLL
328 throw ESocketWinsock(TS("Unable to initialize winsock dll."));
329
330 /* Confirm that the WinSock DLL supports 2.0 */
331
332 if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 0) {
333 // We couldn't find a usable winsock dll
334 WSACleanup();
335 throw ESocketDll(TS("Winsock dll version is not 2.0 or higher."));
336 }
337}
338
339// Deinitialize WinSock DLL
341{
342 if (WSACleanup() != 0)
343 throw ESocketWinsock(TS("Unable to deinitialize winsock dll."));
344}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
virtual INT Receive(LPSTR lpsBuffer, UINT nLength)
Definition: socket.cpp:126
LPCServerSocket ServerSocket
Definition: socket.h:111
virtual VOID OnClose()
Definition: socket.h:109
CServerSocket * GetServerSocket()
Definition: socket.cpp:149
virtual INT Transmit(LPCSTR lpsBuffer, UINT nLength)
Definition: socket.cpp:109
virtual INT SendText(LPCSTR lpsText)
Definition: socket.cpp:115
virtual VOID MessageLoop()
Definition: socket.cpp:132
virtual VOID OnRead()
Definition: socket.h:107
virtual ~CServerClientThread()
Definition: socket.cpp:162
CServerClientSocket * ClientSocket
Definition: socket.h:120
virtual LPCServerClientSocket OnGetSocket(LPCServerSocket lpServerSocket)
Definition: socket.cpp:306
virtual ~CServerSocket()
Definition: socket.cpp:176
virtual VOID OnAccept(LPCServerClientThread lpThread)
Definition: socket.h:132
virtual VOID Open()
Definition: socket.cpp:183
virtual VOID MessageLoop()
Definition: socket.cpp:251
virtual LPCServerClientThread OnGetThread(LPCServerClientSocket lpSocket)
Definition: socket.cpp:312
virtual VOID Close()
Definition: socket.cpp:212
CList< LPCServerClientThread > Connections
Definition: socket.h:137
virtual VOID SetPort(UINT nPort)
Definition: socket.cpp:243
VOID RemoveClient(LPCServerClientThread lpClient)
Definition: socket.cpp:300
VOID InsertClient(LPCServerClientThread lpClient)
Definition: socket.cpp:294
LONG Events
Definition: socket.h:95
virtual ~CSocket()
Definition: socket.cpp:36
SOCKET Socket
Definition: socket.h:89
UINT Port
Definition: socket.h:92
virtual LONG GetEvents()
Definition: socket.cpp:84
virtual SOCKET GetSocket()
Definition: socket.cpp:41
virtual VOID SetSockAddrIn(SOCKADDR_IN sockaddrin)
Definition: socket.cpp:60
CSocket()
Definition: socket.cpp:18
virtual VOID SetSocket(SOCKET socket)
Definition: socket.cpp:47
virtual VOID SetEvents(LONG lEvents)
Definition: socket.cpp:66
virtual VOID Open()
Definition: socket.cpp:90
virtual VOID Close()
Definition: socket.cpp:95
virtual SOCKADDR_IN GetSockAddrIn()
Definition: socket.cpp:54
SOCKADDR_IN SockAddrIn
Definition: socket.h:90
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const WCHAR crlf[]
Definition: object.c:1018
#define FAR
Definition: zlib.h:34
BOOL WSAAPI WSACloseEvent(IN WSAEVENT hEvent)
Definition: event.c:23
INT WSAAPI WSAEnumNetworkEvents(IN SOCKET s, IN WSAEVENT hEventObject, OUT LPWSANETWORKEVENTS lpNetworkEvents)
Definition: event.c:94
DWORD WSAAPI WSAWaitForMultipleEvents(IN DWORD cEvents, IN CONST WSAEVENT FAR *lphEvents, IN BOOL fWaitAll, IN DWORD dwTimeout, IN BOOL fAlertable)
Definition: event.c:75
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
INT WSAAPI WSAEventSelect(IN SOCKET s, IN WSAEVENT hEventObject, IN LONG lNetworkEvents)
Definition: select.c:182
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
#define assert(x)
Definition: debug.h:53
#define SOCK_STREAM
Definition: tcpip.h:118
#define AF_INET
Definition: tcpip.h:117
unsigned short WORD
Definition: ntddk_ex.h:93
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define INADDR_ANY
Definition: inet.h:53
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define htons(x)
Definition: module.h:215
#define TS(x)
Definition: error.h:11
#define MAX_PENDING_CONNECTS
Definition: socket.h:15
#define closesocket
Definition: ncftp.h:477
unsigned int UINT
Definition: ndis.h:50
long LONG
Definition: pedump.c:60
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
VOID DeinitWinsock()
Definition: socket.cpp:340
VOID InitWinsock()
Definition: socket.cpp:319
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
WORD wVersion
Definition: winsock.h:517
struct in_addr sin_addr
Definition: winsock.h:512
short sin_family
Definition: winsock.h:510
u_short sin_port
Definition: winsock.h:511
#define MAKEWORD(a, b)
Definition: typedefs.h:248
int32_t INT
Definition: typedefs.h:58
_In_ DWORD nLength
Definition: wincon.h:473
WINSOCK_API_LINKAGE WSAEVENT WSAAPI WSACreateEvent(void)
Definition: event.c:42
#define WSA_INVALID_EVENT
Definition: winsock2.h:623
#define FD_READ
Definition: winsock.h:405
int PASCAL FAR WSACleanup(void)
Definition: startup.c:60
#define INVALID_SOCKET
Definition: winsock.h:332
#define FD_CLOSE
Definition: winsock.h:410
UINT_PTR SOCKET
Definition: winsock.h:47
#define SOCKET_ERROR
Definition: winsock.h:333
#define FD_CONNECT
Definition: winsock.h:409
#define FD_ACCEPT
Definition: winsock.h:408
_In_ ULONG _In_ BOOLEAN Active
Definition: potypes.h:561
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175