3 * Copyright (C) 2005 ReactOS Team
5 * LICENCE: GPL - See COPYING in the top level directory
6 * PROJECT: ReactOS simple TCP/IP services
7 * FILE: apps/utils/net/tcpsvcs/skelserver.c
8 * PURPOSE: Provide CharGen, Daytime, Discard, Echo, and Qotd services
9 * PROGRAMMERS: Ged Murphy (gedmurphy@gmail.com)
20 DWORD WINAPI
StartServer(LPVOID lpParam
)
22 SOCKET ListeningSocket
;
23 const TCHAR
* HostIP
= "127.0.0.1";
26 pServices
= (PSERVICES
)lpParam
;
28 ListeningSocket
= SetUpListener(HostIP
, htons(pServices
->Port
));
29 if (ListeningSocket
== INVALID_SOCKET
)
31 _tprintf(_T("error setting up socket\n"));
35 _tprintf(_T("%s is waiting for connections on port %d...\n"),
36 pServices
->Name
, pServices
->Port
);
39 AcceptConnections(ListeningSocket
, pServices
->Service
, pServices
->Name
);
40 printf("Acceptor restarting...\n");
43 /* won't see this yet as we kill the service with ctrl+c */
44 _tprintf(_T("Detaching Winsock2...\n"));
50 SOCKET
SetUpListener(const char* ServAddr
, int Port
)
55 Sock
= socket(AF_INET
, SOCK_STREAM
, 0);
56 if (Sock
!= INVALID_SOCKET
)
58 Server
.sin_family
= AF_INET
;
59 Server
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
60 Server
.sin_port
= Port
;
61 if (bind(Sock
, (SOCKADDR
*)&Server
, sizeof(SOCKADDR_IN
)) != SOCKET_ERROR
)
63 listen(Sock
, SOMAXCONN
);
67 printf("bind() failed\n");
70 return INVALID_SOCKET
;
76 VOID
AcceptConnections(SOCKET ListeningSocket
,
77 LPTHREAD_START_ROUTINE Service
, TCHAR
*Name
)
81 INT nAddrSize
= sizeof(Client
);
86 Sock
= accept(ListeningSocket
, (SOCKADDR
*)&Client
, &nAddrSize
);
87 if (Sock
!= INVALID_SOCKET
)
89 _tprintf(_T("Accepted connection to %s server from %s:%d\n"),
90 Name
, inet_ntoa(Client
.sin_addr
), ntohs(Client
.sin_port
));
91 _tprintf(_T("Creating new thread for %s\n"), Name
);
92 CreateThread(0, 0, Service
, (void*)Sock
, 0, &ThreadID
);
96 _tprintf(_T("accept() failed\n"));
102 BOOL
ShutdownConnection(SOCKET Sock
, BOOL bRec
)
104 /* Disallow any further data sends. This will tell the other side
105 that we want to go away now. If we skip this step, we don't
106 shut the connection down nicely. */
107 if (shutdown(Sock
, SD_SEND
) == SOCKET_ERROR
)
109 _tprintf(_T("Error in shutdown"));
113 /* Receive any extra data still sitting on the socket. After all
114 data is received, this call will block until the remote host
115 acknowledges the TCP control packet sent by the shutdown above.
116 Then we'll get a 0 back from recv, signalling that the remote
117 host has closed its side of the connection. */
120 char ReadBuffer
[BUF
];
121 int NewBytes
= recv(Sock
, ReadBuffer
, BUF
, 0);
122 if (NewBytes
== SOCKET_ERROR
)
124 else if (NewBytes
!= 0)
125 _tprintf(_T("FYI, received %d unexpected bytes during shutdown\n"), NewBytes
);
128 /* Close the socket. */
129 if (closesocket(Sock
) == SOCKET_ERROR
)