xref: /reactos/base/services/tcpsvcs/echo.c (revision 3e1f4074)
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     WCHAR 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             swprintf(logBuf, L"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                     swprintf(logBuf, L"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(L"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(L"Peer unexpectedly dropped connection!", 0, 0, LOG_FILE);
51                     return FALSE;
52                 }
53             }
54         }
55         else if (readBytes == SOCKET_ERROR)
56         {
57             LogEvent(L"Echo: socket error", WSAGetLastError(), 0, LOG_ERROR);
58             return FALSE;
59         }
60     } while ((readBytes != 0) && (!bShutdown));
61 
62     if (!bShutdown)
63         LogEvent(L"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(L"Echo: EchoIncomingPackets failed", 0, 0, LOG_FILE);
77         retVal = 1;
78     }
79 
80     LogEvent(L"Echo: Shutting connection down", 0, 0, LOG_FILE);
81 
82     if (ShutdownConnection(sock, TRUE))
83     {
84         LogEvent(L"Echo: Connection is down", 0, 0, LOG_FILE);
85     }
86     else
87     {
88         LogEvent(L"Echo: Connection shutdown failed", 0, 0, LOG_FILE);
89         retVal = 1;
90     }
91 
92     LogEvent(L"Echo: Terminating thread", 0, 0, LOG_FILE);
93     ExitThread(retVal);
94 }
95