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 const TCHAR
* HostIP
= "127.0.0.1";
25 pServices
= (PSERVICES
)lpParam
;
27 SOCKET ListeningSocket
= SetUpListener(HostIP
, htons(pServices
->Port
));
28 if (ListeningSocket
== INVALID_SOCKET
)
30 _tprintf(_T("error setting up socket\n"));
34 _tprintf(_T("%s is waiting for connections on port %d...\n"),
35 pServices
->Name
, pServices
->Port
);
38 AcceptConnections(ListeningSocket
, pServices
->Service
, pServices
->Name
);
39 printf("Acceptor restarting...\n");
42 /* won't see this yet as we kill the service with ctrl+c */
43 _tprintf(_T("Detaching Winsock2...\n"));
49 SOCKET
SetUpListener(const char* ServAddr
, int Port
)
54 Sock
= socket(AF_INET
, SOCK_STREAM
, 0);
55 if (Sock
!= INVALID_SOCKET
)
57 Server
.sin_family
= AF_INET
;
58 Server
.sin_addr
.s_addr
= htonl(INADDR_ANY
);
59 Server
.sin_port
= Port
;
60 if (bind(Sock
, (SOCKADDR
*)&Server
, sizeof(SOCKADDR_IN
)) != SOCKET_ERROR
)
62 listen(Sock
, SOMAXCONN
);
66 printf("bind() failed\n");
69 return INVALID_SOCKET
;
75 VOID
AcceptConnections(SOCKET ListeningSocket
,
76 LPTHREAD_START_ROUTINE Service
, TCHAR
*Name
)
80 INT nAddrSize
= sizeof(Client
);
85 Sock
= accept(ListeningSocket
, (SOCKADDR
*)&Client
, &nAddrSize
);
86 if (Sock
!= INVALID_SOCKET
)
88 _tprintf(_T("Accepted connection to %s server from %s:%d\n"),
89 Name
, inet_ntoa(Client
.sin_addr
), ntohs(Client
.sin_port
));
90 _tprintf(_T("Creating new thread for %s\n"), Name
);
91 CreateThread(0, 0, Service
, (void*)Sock
, 0, &ThreadID
);
95 _tprintf(_T("accept() failed\n"));
101 BOOL
ShutdownConnection(SOCKET Sock
, BOOL bRec
)
103 /* Disallow any further data sends. This will tell the other side
104 that we want to go away now. If we skip this step, we don't
105 shut the connection down nicely. */
106 if (shutdown(Sock
, SD_SEND
) == SOCKET_ERROR
)
108 _tprintf(_T("Error in shutdown"));
112 /* Receive any extra data still sitting on the socket. After all
113 data is received, this call will block until the remote host
114 acknowledges the TCP control packet sent by the shutdown above.
115 Then we'll get a 0 back from recv, signalling that the remote
116 host has closed its side of the connection. */
119 char ReadBuffer
[BUF
];
120 int NewBytes
= recv(Sock
, ReadBuffer
, BUF
, 0);
121 if (NewBytes
== SOCKET_ERROR
)
123 else if (NewBytes
!= 0)
124 _tprintf(_T("FYI, received %d unexpected bytes during shutdown\n"), NewBytes
);
127 /* Close the socket. */
128 if (closesocket(Sock
) == SOCKET_ERROR
)