telnetsocket.cpp
上传用户:zhangwei01
上传日期:2007-01-09
资源大小:25k
文件大小:6k
源码类别:

Telnet服务器

开发平台:

Visual C++

  1. ///////////////////////////////////////////////////////////////////////
  2. // Filename: telnetsocket.cpp
  3. //
  4. // Date    : 27-May-2001
  5. // Author  : J.Hogendoorn ( jeroenhog@gmx.net )
  6. //
  7. // Note    : this code may be used anywhere as long
  8. //         : as this comment remains. 
  9. //
  10. ///////////////////////////////////////////////////////////////////////
  11. #include "stdafx.h"
  12. #include "telnetsocket.h"
  13. //////////////////////////////////////////////////////////////////////
  14. // Method  : constructor
  15. // In      : none
  16. // Out     : none
  17. // Purpose : initializes some member vars
  18. // Note    : 
  19. CTelnetSocket::CTelnetSocket()
  20. {
  21. m_sLastError  = "";
  22. m_iSock       = 0;
  23. m_iClientSock = 0;
  24. m_sClientIp   = "";
  25. }
  26. //////////////////////////////////////////////////////////////////////
  27. // Method  : destructor
  28. // In      : none
  29. // Out     : none
  30. // Purpose : cleans up windows socket stuff
  31. // Note    : 
  32. CTelnetSocket::~CTelnetSocket()
  33. {
  34. // cleanup windows sockets
  35. WSACleanup();  
  36. }
  37. //////////////////////////////////////////////////////////////////////
  38. // Method  : closeClientSocket
  39. // In      : none
  40. // Out     : none
  41. // Purpose : closes the client socket
  42. // Note    : 
  43. void CTelnetSocket::closeClientSocket()
  44. {
  45. closesocket(m_iClientSock);
  46. }
  47. //////////////////////////////////////////////////////////////////////
  48. // Method  : closeServerSocket
  49. // In      : none
  50. // Out     : none
  51. // Purpose : closes the server socket
  52. // Note    : 
  53. void CTelnetSocket::closeServerSocket()
  54. {
  55. closesocket(m_iSock);
  56. }
  57. //////////////////////////////////////////////////////////////////////
  58. // Method  : initialize
  59. // In      : port number to run on
  60. // Out     : true if succeeded, false if not
  61. // Purpose : initializes the connection
  62. // Note    : 
  63. bool CTelnetSocket::initialize( DWORD dwPortNr )
  64. {
  65. // Windows socket initialization
  66. WORD    wVersionRequested; 
  67. WSADATA wsaData; 
  68. wVersionRequested = MAKEWORD(1, 1); 
  69. // Find winsock version
  70. if ( WSAStartup(wVersionRequested, &wsaData) )
  71. {
  72. m_sLastError = "Incorrect winsock version";
  73. return false;
  74. }
  75. // create socket
  76. m_iSock = socket(AF_INET, SOCK_STREAM, 0);
  77. if ( m_iSock == INVALID_SOCKET  )
  78. {
  79. m_sLastError = "Error while creating socket";
  80. return false;
  81. }
  82. int iOptval = 1;
  83. if ( setsockopt( m_iSock, SOL_SOCKET, SO_REUSEADDR, (char *) &iOptval, sizeof(int)) )
  84. {
  85. m_sLastError = "setsockopt failed";
  86. return false;
  87. }
  88. m_siUs.sin_family      = AF_INET;
  89. m_siUs.sin_port        = htons( USHORT(dwPortNr) );
  90. m_siUs.sin_addr.s_addr = INADDR_ANY;
  91. // Bind to the given port
  92. if ( bind( m_iSock, (struct sockaddr *) &m_siUs, sizeof(m_siUs) ) )
  93. {
  94. m_sLastError = "bind failed";
  95. return false;
  96. }
  97. // change to passive socket
  98. if ( listen( m_iSock , SOMAXCONN ) )
  99. {
  100. m_sLastError = "listen failed";
  101. return false;
  102. }
  103. return true;
  104. }
  105. //////////////////////////////////////////////////////////////////////
  106. // Method  : waitForConnection
  107. // In      : none
  108. // Out     : true if succeeded, false if not
  109. // Purpose : waits for a client to connect
  110. // Note    : 
  111. bool CTelnetSocket::waitForConnection()
  112. {
  113. // wait for port
  114. int         iLen        = sizeof( sockaddr_in );
  115. int         iClientSock = 0;
  116. // fill with zero terms
  117. memset( &m_siThem , 0 , sizeof( m_siThem) );
  118. // wait for connetion
  119. m_iClientSock = accept( m_iSock, (struct sockaddr *)&(m_siThem) , &iLen );
  120. if ( m_iClientSock == INVALID_SOCKET )
  121. {
  122. m_sLastError = "accept failed";
  123. return false;
  124. }
  125. // get client ip address
  126. char szClientIp[255];
  127. strncpy( szClientIp, inet_ntoa(m_siThem.sin_addr), 128);
  128. m_sClientIp = szClientIp;
  129. return true;
  130. }
  131. //////////////////////////////////////////////////////////////////////
  132. // Method  : sendData
  133. // In      : data to send
  134. // Out     : true if succeeded, false if not
  135. // Purpose : sends data to the client
  136. // Note    : 
  137. bool CTelnetSocket::sendData( const CString& sData )
  138. {
  139. if ( send( m_iClientSock , sData , sData.GetLength() , 0 ) != sData.GetLength() )
  140. {
  141. m_sLastError = "sending data to client failed";
  142. return false;
  143. }
  144. return true;
  145. }
  146. //////////////////////////////////////////////////////////////////////
  147. // Method  : waitForData
  148. // In      : is password ( echo's * in stead of types char )
  149. // Out     : true if succeeded, false if not, and the data that was typed
  150. // Purpose : waits for a user to type something followed by ENTER
  151. // Note    : only backspace is implemented as a 'special' char
  152. bool CTelnetSocket::waitForData( CString& sData , bool bIsPassword /*false*/ )
  153. {
  154. // global would be faster....
  155. CString sValidChars = "abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890~`!@#$%^&*()-_=+{[}]\|;:'"<,>.?/";
  156. int  iSizeEchoBuf = 0;
  157. char szBuf[4];
  158. char szEchoBuf[4];
  159. // empty the buffers
  160. memset( szBuf     , 0 , 4 );
  161. memset( szEchoBuf , 0 , 4 );
  162. while ( szBuf[0] != 13 )
  163. {
  164. // empty the buffers
  165. memset( szBuf     , 0 , 4 );
  166. memset( szEchoBuf , 0 , 4 );
  167. iSizeEchoBuf = 0;
  168. // receive max 3 bytes ( e.g. arrow up will be chr(27) + [ + A )
  169. int ierr = recv( m_iClientSock, szBuf , 4 , 0);
  170. if (ierr < 1 ) 
  171. m_sLastError = "receiving data from client failed";
  172. return false;
  173. if (( szBuf[0]                     ==  13 ) || // enter pressed
  174.     ( szBuf[0]                     ==  8  ) || // backspace
  175. ( sValidChars.Find( szBuf[0] ) != -1  )) // 'ordinary' character
  176. {
  177. if ( szBuf[0] == 8 ) // backspace
  178. {
  179. // backspace pressed
  180. if ( sData.GetLength() > 0 )
  181. {
  182. // cut off one char
  183. sData        = sData.Mid( 0 , sData.GetLength() -1 );
  184. szEchoBuf[0] = 8;
  185. szEchoBuf[1] = 32;
  186. szEchoBuf[2] = 8;
  187. iSizeEchoBuf = 3;
  188. }
  189. else
  190. {
  191. continue;
  192. }
  193. // enter pressed
  194. else if ( szBuf[0] == 13 )
  195. {
  196. szEchoBuf[0] = 13;
  197. szEchoBuf[1] = 10;
  198. iSizeEchoBuf = 2;
  199. }
  200. else
  201. {
  202. // add to result buffer
  203. sData += szBuf[0];
  204. // ordinary char pressed
  205. if ( bIsPassword )
  206. {
  207. // echo a '*'
  208. strcpy( szEchoBuf , "*" );
  209. iSizeEchoBuf = 1;
  210. }
  211. else
  212. {
  213. // echo the pressed char
  214. memcpy( szEchoBuf , szBuf , 1 );
  215. iSizeEchoBuf = 1;
  216. }
  217. }
  218. // echo
  219. if ( send( m_iClientSock , szEchoBuf , iSizeEchoBuf , 0 ) != iSizeEchoBuf )
  220. {
  221. m_sLastError = "sending data to client failed";
  222. return false;
  223. }
  224. }
  225. }
  226. return true;
  227. }