Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenskelserver.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS simple TCP/IP services 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: /base/services/tcpsvcs/skelserver.c 00005 * PURPOSE: Sets up a server and listens for connections 00006 * COPYRIGHT: Copyright 2005 - 2008 Ged Murphy <gedmurphy@gmail.com> 00007 * 00008 */ 00009 00010 #include "tcpsvcs.h" 00011 00012 #define BUF 1024 00013 00014 static SOCKET 00015 SetUpListener(USHORT Port) 00016 { 00017 SOCKET sock; 00018 SOCKADDR_IN server; 00019 BOOL bSetup = FALSE; 00020 00021 sock = socket(AF_INET, SOCK_STREAM, 0); 00022 if (sock != INVALID_SOCKET) 00023 { 00024 server.sin_family = AF_INET; 00025 server.sin_addr.s_addr = htonl(INADDR_ANY); 00026 server.sin_port = Port; 00027 00028 if (bind(sock, (SOCKADDR*)&server, sizeof(SOCKADDR_IN)) != SOCKET_ERROR) 00029 { 00030 if (listen(sock, SOMAXCONN) != SOCKET_ERROR) 00031 { 00032 bSetup = TRUE; 00033 } 00034 else 00035 { 00036 LogEvent(L"listen() failed", WSAGetLastError(), 0, LOG_ERROR); 00037 } 00038 } 00039 else 00040 { 00041 LogEvent(L"bind() failed", WSAGetLastError(), 0, LOG_ERROR); 00042 } 00043 } 00044 else 00045 { 00046 LogEvent(L"socket() failed", WSAGetLastError(), 0, LOG_ERROR); 00047 } 00048 00049 return bSetup ? sock : INVALID_SOCKET; 00050 } 00051 00052 00053 static VOID 00054 AcceptConnections(SOCKET listeningSocket, 00055 LPTHREAD_START_ROUTINE lpService, 00056 LPWSTR lpName) 00057 { 00058 SOCKADDR_IN client; 00059 SOCKET sock; 00060 HANDLE hThread; 00061 TIMEVAL timeVal; 00062 FD_SET readFD; 00063 WCHAR logBuf[256]; 00064 INT timeOut = 2000; 00065 00066 timeVal.tv_sec = timeOut / 1000; 00067 timeVal.tv_usec = timeOut % 1000; 00068 00069 while (!bShutdown) 00070 { 00071 INT selRet = 0; 00072 00073 FD_ZERO(&readFD); 00074 FD_SET(listeningSocket, &readFD); 00075 00076 selRet = select(0, &readFD, NULL, NULL, &timeVal); 00077 if (selRet > 0) 00078 { 00079 if (!bShutdown || FD_ISSET(listeningSocket, &readFD)) 00080 { 00081 INT addrSize = sizeof(SOCKADDR_IN); 00082 00083 sock = accept(listeningSocket, (SOCKADDR*)&client, &addrSize); 00084 if (sock != INVALID_SOCKET) 00085 { 00086 _swprintf(logBuf, 00087 L"Accepted connection to %s server from %S:%d", 00088 lpName, 00089 inet_ntoa(client.sin_addr), 00090 ntohs(client.sin_port)); 00091 LogEvent(logBuf, 0, 0, LOG_FILE); 00092 00093 _swprintf(logBuf, L"Creating worker thread for %s", lpName); 00094 LogEvent(logBuf, 0, 0, LOG_FILE); 00095 00096 if (!bShutdown) 00097 { 00098 hThread = CreateThread(0, 0, lpService, (void*)sock, 0, NULL); 00099 if (hThread != NULL) 00100 { 00101 CloseHandle(hThread); 00102 } 00103 else 00104 { 00105 _swprintf(logBuf, L"Failed to start worker thread for the %s server", 00106 lpName); 00107 LogEvent(logBuf, 0, 0, LOG_FILE); 00108 } 00109 } 00110 } 00111 else 00112 { 00113 LogEvent(L"accept failed", WSAGetLastError(), 0, LOG_ERROR); 00114 } 00115 } 00116 } 00117 else if (selRet == SOCKET_ERROR) 00118 { 00119 LogEvent(L"select failed", WSAGetLastError(), 0, LOG_ERROR); 00120 } 00121 } 00122 } 00123 00124 BOOL 00125 ShutdownConnection(SOCKET sock, 00126 BOOL bRec) 00127 { 00128 WCHAR logBuf[256]; 00129 00130 /* Disallow any further data sends. This will tell the other side 00131 that we want to go away now. If we skip this step, we don't 00132 shut the connection down nicely. */ 00133 if (shutdown(sock, SD_SEND) == SOCKET_ERROR) 00134 { 00135 LogEvent(L"Error in shutdown()", WSAGetLastError(), 0, LOG_ERROR); 00136 return FALSE; 00137 } 00138 00139 /* Receive any extra data still sitting on the socket 00140 before we close it */ 00141 if (bRec) 00142 { 00143 CHAR readBuffer[BUF]; 00144 INT ret; 00145 00146 do 00147 { 00148 ret = recv(sock, readBuffer, BUF, 0); 00149 if (ret >= 0) 00150 { 00151 _swprintf(logBuf, L"FYI, received %d unexpected bytes during shutdown", ret); 00152 LogEvent(logBuf, 0, 0, LOG_FILE); 00153 } 00154 } while (ret > 0); 00155 } 00156 00157 closesocket(sock); 00158 00159 return TRUE; 00160 } 00161 00162 00163 DWORD WINAPI 00164 StartServer(LPVOID lpParam) 00165 { 00166 SOCKET listeningSocket; 00167 PSERVICES pServices; 00168 TCHAR logBuf[256]; 00169 00170 pServices = (PSERVICES)lpParam; 00171 00172 _swprintf(logBuf, L"Starting %s server", pServices->lpName); 00173 LogEvent(logBuf, 0, 0, LOG_FILE); 00174 00175 if (!bShutdown) 00176 { 00177 listeningSocket = SetUpListener(htons(pServices->Port)); 00178 if (!bShutdown && listeningSocket != INVALID_SOCKET) 00179 { 00180 _swprintf(logBuf, 00181 L"%s is waiting for connections on port %d", 00182 pServices->lpName, 00183 pServices->Port); 00184 LogEvent(logBuf, 0, 0, LOG_FILE); 00185 00186 AcceptConnections(listeningSocket, pServices->lpService, pServices->lpName); 00187 } 00188 else 00189 { 00190 LogEvent(L"Socket error when setting up listener", 0, 0, LOG_FILE); 00191 } 00192 } 00193 00194 _swprintf(logBuf, 00195 L"Exiting %s thread", 00196 pServices->lpName); 00197 LogEvent(logBuf, 0, 0, LOG_FILE); 00198 ExitThread(0); 00199 } Generated on Sun May 27 2012 04:17:54 for ReactOS by
1.7.6.1
|