- Added daytime and quote of the day services
[reactos.git] / reactos / apps / utils / net / tcpsvcs / skelserver.c
1 #include <stdio.h>
2 #include <winsock2.h>
3 #include <tchar.h>
4 #include "tcpsvcs.h"
5
6
7 DWORD WINAPI StartServer(LPVOID lpParam)
8 {
9 const TCHAR* HostIP = "127.0.0.1";
10 DWORD RetVal;
11 WSADATA wsaData;
12 PSERVICES pServices;
13
14 pServices = (PSERVICES)lpParam;
15
16 if ((RetVal = WSAStartup(MAKEWORD(2, 2), &wsaData)) != 0)
17 {
18 _tprintf(_T("WSAStartup() failed : %lu\n"), RetVal);
19 return -1;
20 }
21
22 SOCKET ListeningSocket = SetUpListener(HostIP, htons(pServices->Port));
23 if (ListeningSocket == INVALID_SOCKET)
24 {
25 _tprintf(_T("error setting up socket\n"));
26 return 3;
27 }
28
29 _tprintf(_T("Waiting for connections...\n"));
30 while (1)
31 {
32 AcceptConnections(ListeningSocket, pServices->Service);
33 printf("Acceptor restarting...\n");
34 }
35
36 /* won't see this yet as we kill the service */
37 _tprintf(_T("Detaching Winsock2...\n"));
38 WSACleanup();
39 return 0;
40 }
41
42
43 SOCKET SetUpListener(const char* ServAddr, int Port)
44 {
45 SOCKET Sock;
46 SOCKADDR_IN Server;
47
48 Sock = socket(AF_INET, SOCK_STREAM, 0);
49 if (Sock != INVALID_SOCKET)
50 {
51 Server.sin_family = AF_INET;
52 Server.sin_addr.s_addr = htonl(INADDR_ANY);
53 Server.sin_port = Port;
54 if (bind(Sock, (SOCKADDR*)&Server, sizeof(SOCKADDR_IN)) != SOCKET_ERROR)
55 {
56 listen(Sock, SOMAXCONN);
57 return Sock;
58 }
59 else
60 printf("bind() failed\n");
61
62 }
63 return INVALID_SOCKET;
64 }
65
66
67
68
69 VOID AcceptConnections(SOCKET ListeningSocket, LPTHREAD_START_ROUTINE Service)
70 {
71 SOCKADDR_IN Client;
72 SOCKET Sock;
73 INT nAddrSize = sizeof(Client);
74 DWORD ThreadID;
75
76 while (1)
77 {
78 Sock = accept(ListeningSocket, (SOCKADDR*)&Client, &nAddrSize);
79 if (Sock != INVALID_SOCKET)
80 {
81 _tprintf(_T("Accepted connection from %s:%d\n"),
82 inet_ntoa(Client.sin_addr), ntohs(Client.sin_port));
83 _tprintf(_T("About to create thread\n"));
84 CreateThread(0, 0, Service, (void*)Sock, 0, &ThreadID);
85 }
86 else
87 {
88 _tprintf(_T("accept() failed\n"));
89 return;
90 }
91 }
92 }
93
94 BOOL ShutdownConnection(SOCKET Sock, BOOL bRec)
95 {
96 /* Disallow any further data sends. This will tell the other side
97 that we want to go away now. If we skip this step, we don't
98 shut the connection down nicely. */
99 if (shutdown(Sock, SD_SEND) == SOCKET_ERROR)
100 {
101 _tprintf(_T("Error in shutdown"));
102 return FALSE;
103 }
104
105 /* Receive any extra data still sitting on the socket. After all
106 data is received, this call will block until the remote host
107 acknowledges the TCP control packet sent by the shutdown above.
108 Then we'll get a 0 back from recv, signalling that the remote
109 host has closed its side of the connection. */
110 if (bRec)
111 {
112 char ReadBuffer[BUF];
113 int NewBytes = recv(Sock, ReadBuffer, BUF, 0);
114 if (NewBytes == SOCKET_ERROR)
115 return FALSE;
116 else if (NewBytes != 0)
117 _tprintf(_T("FYI, received %d unexpected bytes during shutdown\n"), NewBytes);
118 }
119
120 /* Close the socket. */
121 if (closesocket(Sock) == SOCKET_ERROR)
122 return FALSE;
123
124 return TRUE;
125 }