Create a branch for network fixes.
[reactos.git] / base / services / tcpsvcs / echo.c
1 /*
2 * PROJECT: ReactOS simple TCP/IP services
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: /base/services/tcpsvcs/echo.c
5 * PURPOSE: Returns whatever input the client sends
6 * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy@reactos.org>
7 *
8 */
9
10 #include "tcpsvcs.h"
11
12 #define RECV_BUF 1024
13
14 static BOOL
15 EchoIncomingPackets(SOCKET sock)
16 {
17 CHAR readBuffer[RECV_BUF];
18 TCHAR logBuf[256];
19 INT totalSentBytes;
20 INT readBytes;
21 INT retVal;
22
23 do
24 {
25 readBytes = recv(sock, readBuffer, RECV_BUF, 0);
26 if (readBytes > 0)
27 {
28 _stprintf(logBuf, _T("Received %d bytes from client"), readBytes);
29 LogEvent(logBuf, 0, 0, LOG_FILE);
30
31 totalSentBytes = 0;
32 while (!bShutdown && totalSentBytes < readBytes)
33 {
34 retVal = send(sock, readBuffer + totalSentBytes, readBytes - totalSentBytes, 0);
35 if (retVal > 0)
36 {
37 _stprintf(logBuf, _T("Sent %d bytes back to client"), retVal);
38 LogEvent(logBuf, 0, 0, LOG_FILE);
39 totalSentBytes += retVal;
40 }
41 else if (retVal == SOCKET_ERROR)
42 {
43 LogEvent(_T("Echo: socket error"), WSAGetLastError(), 0, LOG_ERROR);
44 return FALSE;
45 }
46 else
47 {
48 /* Client closed connection before we could reply to
49 all the data it sent, so quit early. */
50 LogEvent(_T("Peer unexpectedly dropped connection!"), 0, 0, LOG_FILE);
51 return FALSE;
52 }
53 }
54 }
55 else if (readBytes == SOCKET_ERROR)
56 {
57 LogEvent(_T("Echo: socket error"), WSAGetLastError(), 0, LOG_ERROR);
58 return FALSE;
59 }
60 } while ((readBytes != 0) && (!bShutdown));
61
62 if (!bShutdown)
63 LogEvent(_T("Echo: Connection closed by peer"), 0, 0, LOG_FILE);
64
65 return TRUE;
66 }
67
68 DWORD WINAPI
69 EchoHandler(VOID* sock_)
70 {
71 DWORD retVal = 0;
72 SOCKET sock = (SOCKET)sock_;
73
74 if (!EchoIncomingPackets(sock))
75 {
76 LogEvent(_T("Echo: EchoIncomingPackets failed"), 0, 0, LOG_FILE);
77 retVal = 1;
78 }
79
80 LogEvent(_T("Echo: Shutting connection down"), 0, 0, LOG_FILE);
81
82 if (ShutdownConnection(sock, TRUE))
83 {
84 LogEvent(_T("Echo: Connection is down"), 0, 0, LOG_FILE);
85 }
86 else
87 {
88 LogEvent(_T("Echo: Connection shutdown failed"), 0, 0, LOG_FILE);
89 retVal = 1;
90 }
91
92 LogEvent(_T("Echo: Terminating thread"), 0, 0, LOG_FILE);
93 ExitThread(retVal);
94 }