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