ReactOS  0.4.14-dev-376-gaedba84
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
71  if (Event == WSA_INVALID_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 
226  CIterator<LPCServerClientThread> *i = Connections.CreateIterator();
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 }
#define SOCKET_ERROR
Definition: winsock.h:333
#define TRUE
Definition: types.h:120
virtual LPCServerClientThread OnGetThread(LPCServerClientSocket lpSocket)
Definition: socket.cpp:312
virtual INT Transmit(LPCSTR lpsBuffer, UINT nLength)
Definition: socket.cpp:109
SOCKET WSAAPI socket(IN INT af, IN INT type, IN INT protocol)
Definition: socklife.c:143
u_short sin_port
Definition: winsock.h:511
BOOL Active
Definition: socket.h:93
virtual ~CSocket()
Definition: socket.cpp:36
#define LOBYTE(W)
Definition: jmemdos.c:487
virtual VOID Open()
Definition: socket.cpp:90
virtual INT Receive(LPSTR lpsBuffer, UINT nLength)
Definition: socket.cpp:126
#define FD_ACCEPT
Definition: winsock.h:408
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define closesocket
#define MAKEWORD(a, b)
Definition: typedefs.h:247
#define FD_CONNECT
Definition: winsock.h:409
INT WSAAPI bind(IN SOCKET s, IN CONST struct sockaddr *name, IN INT namelen)
Definition: socklife.c:36
virtual VOID SetSockAddrIn(SOCKADDR_IN sockaddrin)
Definition: socket.cpp:60
WORD wVersion
Definition: winsock.h:517
virtual VOID SetEvents(LONG lEvents)
Definition: socket.cpp:66
char CHAR
Definition: xmlstorage.h:175
SOCKADDR_IN SockAddrIn
Definition: socket.h:90
_In_ DWORD nLength
Definition: wincon.h:461
INT WSAAPI WSACleanup(VOID)
Definition: startup.c:60
virtual SOCKADDR_IN GetSockAddrIn()
Definition: socket.cpp:54
#define HIBYTE(W)
Definition: jmemdos.c:486
#define TS(x)
Definition: error.h:11
#define INADDR_ANY
Definition: StrAddr.c:4
#define assert(x)
Definition: debug.h:53
#define FD_READ
Definition: winsock.h:405
DWORD WSAAPI WSAWaitForMultipleEvents(IN DWORD cEvents, IN CONST WSAEVENT FAR *lphEvents, IN BOOL fWaitAll, IN DWORD dwTimeout, IN BOOL fAlertable)
Definition: event.c:75
char * LPSTR
Definition: xmlstorage.h:182
virtual INT SendText(LPCSTR lpsText)
Definition: socket.cpp:115
CSocket()
Definition: socket.cpp:18
int32_t INT
Definition: typedefs.h:56
virtual ~CServerSocket()
Definition: socket.cpp:176
virtual VOID Close()
Definition: socket.cpp:95
virtual VOID OnAccept(LPCServerClientThread lpThread)
Definition: socket.h:132
virtual VOID MessageLoop()
Definition: socket.cpp:132
VOID RemoveClient(LPCServerClientThread lpClient)
Definition: socket.cpp:300
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 WSA_INVALID_EVENT
Definition: winsock2.h:595
LONG Events
Definition: socket.h:95
long LONG
Definition: pedump.c:60
virtual VOID Close()
Definition: socket.cpp:212
SOCKET Socket
Definition: socket.h:87
#define FAR
Definition: guiddef.h:36
INT WSAAPI WSAEventSelect(IN SOCKET s, IN WSAEVENT hEventObject, IN LONG lNetworkEvents)
Definition: select.c:182
BOOL WSAAPI WSACloseEvent(IN WSAEVENT hEvent)
Definition: event.c:23
INT WINAPI WSAStartup(IN WORD wVersionRequested, OUT LPWSADATA lpWSAData)
Definition: startup.c:113
smooth NULL
Definition: ftsmooth.c:416
virtual VOID SetSocket(SOCKET socket)
Definition: socket.cpp:47
const char * LPCSTR
Definition: xmlstorage.h:183
virtual VOID OnClose()
Definition: socket.h:109
virtual VOID SetPort(UINT nPort)
Definition: socket.cpp:243
virtual SOCKET GetSocket()
Definition: socket.cpp:41
#define FD_CLOSE
Definition: winsock.h:410
#define INVALID_SOCKET
Definition: winsock.h:332
virtual VOID MessageLoop()
Definition: socket.cpp:251
INT WSAAPI send(IN SOCKET s, IN CONST CHAR FAR *buf, IN INT len, IN INT flags)
Definition: send.c:23
unsigned short WORD
Definition: ntddk_ex.h:93
virtual ~CServerClientThread()
Definition: socket.cpp:162
INT WSAAPI WSAEnumNetworkEvents(IN SOCKET s, IN WSAEVENT hEventObject, OUT LPWSANETWORKEVENTS lpNetworkEvents)
Definition: event.c:94
LPCServerSocket ServerSocket
Definition: socket.h:109
SOCKET WSAAPI accept(IN SOCKET s, OUT LPSOCKADDR addr, OUT INT FAR *addrlen)
Definition: socklife.c:23
CList< LPCServerClientThread > Connections
Definition: socket.h:137
struct in_addr sin_addr
Definition: winsock.h:512
virtual LONG GetEvents()
Definition: socket.cpp:84
#define MAX_PENDING_CONNECTS
Definition: socket.h:15
WSAEVENT WSAAPI WSACreateEvent(VOID)
Definition: event.c:42
virtual LPCServerClientSocket OnGetSocket(LPCServerSocket lpServerSocket)
Definition: socket.cpp:306
VOID InsertClient(LPCServerClientThread lpClient)
Definition: socket.cpp:294
unsigned int UINT
Definition: ndis.h:50
INT WSAAPI listen(IN SOCKET s, IN INT backlog)
Definition: sockctrl.c:123
UINT Port
Definition: socket.h:92
#define AF_INET
Definition: tcpip.h:117
static const WCHAR crlf[]
Definition: object.c:1018
CServerClientSocket * ClientSocket
Definition: socket.h:120
UINT_PTR SOCKET
Definition: winsock.h:47
virtual VOID OnRead()
Definition: socket.h:107
#define SOCK_STREAM
Definition: tcpip.h:118
VOID DeinitWinsock()
Definition: socket.cpp:340
#define htons(x)
Definition: module.h:213
virtual VOID Open()
Definition: socket.cpp:183
INT WSAAPI recv(IN SOCKET s, OUT CHAR FAR *buf, IN INT len, IN INT flags)
Definition: recv.c:23
short sin_family
Definition: winsock.h:510
CServerSocket * GetServerSocket()
Definition: socket.cpp:149
VOID InitWinsock()
Definition: socket.cpp:319