CConnection.cpp
上传用户:young001
上传日期:2007-07-04
资源大小:33k
文件大小:8k
源码类别:

WEB邮件程序

开发平台:

Visual C++

  1. #include "stdafx.h"
  2. #include "CConnection.h"
  3. #define BACKLOG 10
  4. #define TIMEOUT 10
  5. long CConnection::m_count = 0;
  6. CConnection::CConnection () : m_lasterror (0)
  7. {
  8. if (m_count == 0)
  9. {
  10. WSADATA wsd;
  11. int err;
  12. err = WSAStartup (MAKEWORD (1, 1), &wsd);
  13. if (err != 0)
  14. throw CError (err);
  15. }
  16. m_lasterror.m_number = 0;
  17. m_socket = INVALID_SOCKET;
  18. m_count ++;
  19. }
  20. CConnection::CConnection (const char* host, unsigned short port) : m_lasterror (0)
  21. {
  22. if (m_count == 0)
  23. {
  24. WSADATA wsd;
  25. int err;
  26. err = WSAStartup (MAKEWORD (1, 1), &wsd);
  27. if (err != 0)
  28. throw CError (err);
  29. }
  30. m_socket = INVALID_SOCKET;
  31. m_count ++;
  32. if (!Connect (host, port))
  33. {
  34. long err = WSAGetLastError ();
  35. if (err == 0)
  36. err = m_lasterror.m_number;
  37. throw CError (err);
  38. }
  39. }
  40. CConnection::~CConnection ()
  41. {
  42. Disconnect ();
  43. if (m_count == 1)
  44. WSACleanup();
  45. m_count --;
  46. }
  47. void CConnection::GetLastError (char* str, long len)
  48. {
  49. m_lasterror.GetErrorString (str, len);
  50. }
  51. bool CConnection::Connect (const char* host, unsigned short port)
  52. {
  53. Disconnect ();
  54. sockaddr_in addr;
  55. SOCKET sock;
  56. sock = socket (AF_INET, SOCK_STREAM, 0); // create socket
  57. addr.sin_family = AF_INET; // address family Internet
  58. addr.sin_port = htons (port); // set server抯 port number
  59. addr.sin_addr.s_addr = inet_addr (host); // set server抯 IP
  60. if (addr.sin_addr.s_addr == INADDR_NONE)
  61. {
  62. LPHOSTENT lphost;
  63. lphost = gethostbyname(host);
  64. if (lphost != NULL)
  65. addr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
  66. else
  67. {
  68. WSASetLastError(WSAEINVAL);
  69. return FALSE;
  70. }
  71. }
  72. addr.sin_port = htons((u_short)port);
  73. if (connect (sock, (LPSOCKADDR) &addr, sizeof (addr)) == SOCKET_ERROR)
  74. {
  75. long err = WSAGetLastError ();
  76. CConnection::SetLastError (err);
  77. return false;
  78. }
  79. linger lg;
  80. lg.l_onoff = 1;
  81. lg.l_linger = 10;
  82. setsockopt (sock, SOL_SOCKET, SO_LINGER, reinterpret_cast <const char*> (&lg), sizeof (linger));
  83. m_socket = sock;
  84. m_addr = addr;
  85. return true;
  86. }
  87. void CConnection::Disconnect ()
  88. {
  89. if (!IsConnected ())
  90. {
  91. CConnection::SetLastError (WSAENOTCONN);
  92. return;
  93. }
  94. int status;
  95. fd_set readfds;
  96. timeval timeout;
  97. SOCKET s = m_socket;
  98. m_socket = INVALID_SOCKET;
  99. shutdown (s, 0x01);
  100. FD_ZERO (&readfds);
  101. FD_SET (s, &readfds);
  102. timeout.tv_sec = TIMEOUT;
  103. timeout.tv_usec = 0;
  104. status = select (1, &readfds, NULL, NULL, &timeout);
  105. if (status == SOCKET_ERROR)
  106. {
  107. int err = WSAGetLastError();
  108. CConnection::SetLastError (err);
  109. }
  110. // now wait until receive-thread is done (5 seconds max!)
  111. closesocket (s);
  112. }
  113. bool CConnection::PeerInfo (char* host, int host_len, unsigned int* port)
  114. {
  115. if (!IsConnected ())
  116. {
  117. CConnection::SetLastError (WSAENOTCONN);
  118. return false;
  119. }
  120. sockaddr_in addr;
  121. addr = m_addr;
  122. if (port != NULL)
  123. *port = (unsigned int) ntohs (addr.sin_port);
  124. if (host != NULL)
  125. {
  126. char* ip = inet_ntoa (addr.sin_addr);
  127. memset (host, 0, host_len);
  128. int uselen = strlen (ip) + 1;
  129. if (host_len < uselen) uselen = host_len;
  130. memcpy (host, ip, host_len);
  131. }
  132. return true;
  133. }
  134. int CConnection::Send (const char* buffer, int bufferlen)
  135. {
  136. if (!IsConnected ())
  137. {
  138. CConnection::SetLastError (WSAENOTCONN);
  139. return 0;
  140. }
  141. SOCKET sock = m_socket;
  142. return send (sock, buffer, bufferlen, 0);
  143. }
  144. int CConnection::Receive (char* buffer, int bufferlen)
  145. {
  146. int status = recv (m_socket, buffer, bufferlen, 0);
  147. if (status == SOCKET_ERROR)
  148. {
  149. int err = WSAGetLastError();
  150. CConnection::SetLastError (err);
  151. Disconnect ();
  152. return 0;
  153. }
  154. return status;
  155. }
  156. bool CConnection::IsConnected ()
  157. {
  158. bool bConnd;
  159. //bConnd = m_socket != INVALID_SOCKET;
  160. bConnd = !HasConnectionDropped();
  161. return bConnd;
  162. }
  163. CError::CError (long err)
  164. {
  165. m_number = err;
  166. }
  167. long CError::GetErrorString (char* str, long len)
  168. {
  169. static const long lErrCodes[] = 
  170. {
  171. WSAEACCES, 
  172. WSAEADDRINUSE, 
  173. WSAEADDRNOTAVAIL, 
  174. WSAEAFNOSUPPORT, 
  175. WSAEALREADY, 
  176. WSAECONNABORTED, 
  177. WSAECONNREFUSED, 
  178. WSAECONNRESET, 
  179. WSAEDESTADDRREQ, 
  180. WSAEFAULT, 
  181. WSAEHOSTDOWN, 
  182. WSAEHOSTUNREACH, 
  183. WSAEINPROGRESS, 
  184. WSAEINTR, 
  185. WSAEINVAL, 
  186. WSAEISCONN, 
  187. WSAEMFILE, 
  188. WSAEMSGSIZE, 
  189. WSAENETDOWN, 
  190. WSAENETRESET, 
  191. WSAENETUNREACH, 
  192. WSAENOBUFS, 
  193. WSAENOPROTOOPT, 
  194. WSAENOTCONN, 
  195. WSAENOTSOCK, 
  196. WSAEOPNOTSUPP, 
  197. WSAEPFNOSUPPORT, 
  198. WSAEPROCLIM, 
  199. WSAEPROTONOSUPPORT, 
  200. WSAEPROTOTYPE, 
  201. WSAESHUTDOWN, 
  202. WSAESOCKTNOSUPPORT, 
  203. WSAETIMEDOUT, 
  204. WSAEWOULDBLOCK, 
  205. WSAHOST_NOT_FOUND, 
  206. WSANOTINITIALISED, 
  207. WSANO_DATA, 
  208. WSANO_RECOVERY, 
  209. WSASYSNOTREADY, 
  210. WSATRY_AGAIN, 
  211. WSAVERNOTSUPPORTED, 
  212. WSAEDISCON, 
  213. 1001, 
  214. 1002
  215. };
  216. static const char lpErrMsgs[][64] = 
  217. {
  218. "Permission denied.", 
  219. "Address already in use.", 
  220. "Cannot assign requested address.", 
  221. "Address family not supported by protocol family.", 
  222. "Operation already in progress.", 
  223. "Software caused connection abort.", 
  224. "Connection refused.", 
  225. "Connection reset by peer.", 
  226. "Destination address required.", 
  227. "Bad address.", 
  228. "Host is down.", 
  229. "No route to host.", 
  230. "Operation now in progress.", 
  231. "Interrupted function call.", 
  232. "Invalid argument.", 
  233. "Socket is already connected.", 
  234. "Too many open sockets.", 
  235. "Message too long.", 
  236. "Network is down.", 
  237. "Network dropped connection on reset.", 
  238. "Network is unreachable.", 
  239. "No buffer space available.", 
  240. "Bad protocol option.", 
  241. "Socket is not connected.", 
  242. "Socket operation on nonsocket.", 
  243. "Operation not supported.", 
  244. "Protocol family not supported.", 
  245. "Too many processes.", 
  246. "Protocol not supported.", 
  247. "Protocol wrong type for socket.", 
  248. "Cannot send after socket shutdown.", 
  249. "Socket type not supported.", 
  250. "Connection timed out.", 
  251. "Resource temporarily unavailable.", 
  252. "Host not found.", 
  253. "Successful WSAStartup not yet performed.", 
  254. "Valid name, no data record of requested type.", 
  255. "This is a nonrecoverable error.", 
  256. "Network subsystem is unavailable.", 
  257. "Nonauthoritative host not found.", 
  258. "Winsock.dll version out of range.", 
  259. "Graceful shutdown in progress."
  260. "Mutex not created.", 
  261. "Thread not created."
  262. };
  263. for (int i = 0; i < sizeof (lErrCodes) / sizeof (long); i++)
  264. {
  265. if (m_number == lErrCodes[i])
  266. {
  267. int slen = strlen (lpErrMsgs[i]);
  268. if (len > slen + 1) len = slen + 1;
  269. if (str) memcpy (str, lpErrMsgs[i], len);
  270. return slen;
  271. }
  272. }
  273. char lpUnknown[] = "Unknown error.";
  274. int slen = strlen (lpUnknown);
  275. if (len > slen + 1) len = slen + 1;
  276. if (str) memcpy (str, lpUnknown, len);
  277. return slen;
  278. }
  279. BOOL CConnection::HasConnectionDropped()
  280. {
  281. BOOL bConnDropped = FALSE;
  282. INT iRet = 0;
  283. BOOL bOK = TRUE;
  284. if (m_socket == INVALID_SOCKET)
  285. return TRUE;
  286. struct timeval timeout = { 0, 0 };
  287. fd_set readSocketSet;
  288. FD_ZERO(&readSocketSet);
  289. FD_SET(m_socket, &readSocketSet);
  290. iRet = ::select(0, &readSocketSet, NULL, NULL, &timeout);
  291. bOK = (iRet > 0);
  292. if(bOK)
  293. {
  294. bOK = FD_ISSET(m_socket, &readSocketSet);
  295. }
  296. if(bOK)
  297. {
  298. CHAR szBuffer[1] = "";
  299. iRet = ::recv(m_socket, szBuffer, 1, MSG_PEEK);
  300. bOK = (iRet > 0);
  301. if(!bOK)
  302. {
  303. INT iError = ::WSAGetLastError();
  304. bConnDropped = (( iError == WSAENETRESET) ||
  305. (iError == WSAECONNABORTED) ||
  306. (iError == WSAECONNRESET) ||
  307. (iError == WSAEINVAL) ||
  308. (iRet == 0));
  309. }
  310. }
  311.     return(bConnDropped);
  312. }
  313. void CConnection::SetLastError(long err)
  314. {
  315. m_lasterror.m_number = err;
  316. }
  317. void CConnection::GetLocalIP(CString &sIP)
  318. {
  319. char szHostName[128];
  320. const char* pszAddr;
  321. struct hostent * pHost;
  322. sIP = _T("");
  323. int i; 
  324. if( gethostname(szHostName, 128) == 0 )
  325. {
  326. pHost = gethostbyname(szHostName); 
  327. for( i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ ) 
  328. {
  329. pszAddr=inet_ntoa (*(struct in_addr *)pHost->h_addr_list[i]);
  330. //printf("%sn",pszAddr);
  331. sIP += _T(pszAddr);
  332. sIP += _T(" ");
  333. }
  334. }
  335. }