CConnection.cpp
资源名称:mysmtp2.rar [点击查看]
上传用户:young001
上传日期:2007-07-04
资源大小:33k
文件大小:8k
源码类别:
WEB邮件程序
开发平台:
Visual C++
- #include "stdafx.h"
- #include "CConnection.h"
- #define BACKLOG 10
- #define TIMEOUT 10
- long CConnection::m_count = 0;
- CConnection::CConnection () : m_lasterror (0)
- {
- if (m_count == 0)
- {
- WSADATA wsd;
- int err;
- err = WSAStartup (MAKEWORD (1, 1), &wsd);
- if (err != 0)
- throw CError (err);
- }
- m_lasterror.m_number = 0;
- m_socket = INVALID_SOCKET;
- m_count ++;
- }
- CConnection::CConnection (const char* host, unsigned short port) : m_lasterror (0)
- {
- if (m_count == 0)
- {
- WSADATA wsd;
- int err;
- err = WSAStartup (MAKEWORD (1, 1), &wsd);
- if (err != 0)
- throw CError (err);
- }
- m_socket = INVALID_SOCKET;
- m_count ++;
- if (!Connect (host, port))
- {
- long err = WSAGetLastError ();
- if (err == 0)
- err = m_lasterror.m_number;
- throw CError (err);
- }
- }
- CConnection::~CConnection ()
- {
- Disconnect ();
- if (m_count == 1)
- WSACleanup();
- m_count --;
- }
- void CConnection::GetLastError (char* str, long len)
- {
- m_lasterror.GetErrorString (str, len);
- }
- bool CConnection::Connect (const char* host, unsigned short port)
- {
- Disconnect ();
- sockaddr_in addr;
- SOCKET sock;
- sock = socket (AF_INET, SOCK_STREAM, 0); // create socket
- addr.sin_family = AF_INET; // address family Internet
- addr.sin_port = htons (port); // set server抯 port number
- addr.sin_addr.s_addr = inet_addr (host); // set server抯 IP
- if (addr.sin_addr.s_addr == INADDR_NONE)
- {
- LPHOSTENT lphost;
- lphost = gethostbyname(host);
- if (lphost != NULL)
- addr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
- else
- {
- WSASetLastError(WSAEINVAL);
- return FALSE;
- }
- }
- addr.sin_port = htons((u_short)port);
- if (connect (sock, (LPSOCKADDR) &addr, sizeof (addr)) == SOCKET_ERROR)
- {
- long err = WSAGetLastError ();
- CConnection::SetLastError (err);
- return false;
- }
- linger lg;
- lg.l_onoff = 1;
- lg.l_linger = 10;
- setsockopt (sock, SOL_SOCKET, SO_LINGER, reinterpret_cast <const char*> (&lg), sizeof (linger));
- m_socket = sock;
- m_addr = addr;
- return true;
- }
- void CConnection::Disconnect ()
- {
- if (!IsConnected ())
- {
- CConnection::SetLastError (WSAENOTCONN);
- return;
- }
- int status;
- fd_set readfds;
- timeval timeout;
- SOCKET s = m_socket;
- m_socket = INVALID_SOCKET;
- shutdown (s, 0x01);
- FD_ZERO (&readfds);
- FD_SET (s, &readfds);
- timeout.tv_sec = TIMEOUT;
- timeout.tv_usec = 0;
- status = select (1, &readfds, NULL, NULL, &timeout);
- if (status == SOCKET_ERROR)
- {
- int err = WSAGetLastError();
- CConnection::SetLastError (err);
- }
- // now wait until receive-thread is done (5 seconds max!)
- closesocket (s);
- }
- bool CConnection::PeerInfo (char* host, int host_len, unsigned int* port)
- {
- if (!IsConnected ())
- {
- CConnection::SetLastError (WSAENOTCONN);
- return false;
- }
- sockaddr_in addr;
- addr = m_addr;
- if (port != NULL)
- *port = (unsigned int) ntohs (addr.sin_port);
- if (host != NULL)
- {
- char* ip = inet_ntoa (addr.sin_addr);
- memset (host, 0, host_len);
- int uselen = strlen (ip) + 1;
- if (host_len < uselen) uselen = host_len;
- memcpy (host, ip, host_len);
- }
- return true;
- }
- int CConnection::Send (const char* buffer, int bufferlen)
- {
- if (!IsConnected ())
- {
- CConnection::SetLastError (WSAENOTCONN);
- return 0;
- }
- SOCKET sock = m_socket;
- return send (sock, buffer, bufferlen, 0);
- }
- int CConnection::Receive (char* buffer, int bufferlen)
- {
- int status = recv (m_socket, buffer, bufferlen, 0);
- if (status == SOCKET_ERROR)
- {
- int err = WSAGetLastError();
- CConnection::SetLastError (err);
- Disconnect ();
- return 0;
- }
- return status;
- }
- bool CConnection::IsConnected ()
- {
- bool bConnd;
- //bConnd = m_socket != INVALID_SOCKET;
- bConnd = !HasConnectionDropped();
- return bConnd;
- }
- CError::CError (long err)
- {
- m_number = err;
- }
- long CError::GetErrorString (char* str, long len)
- {
- static const long lErrCodes[] =
- {
- WSAEACCES,
- WSAEADDRINUSE,
- WSAEADDRNOTAVAIL,
- WSAEAFNOSUPPORT,
- WSAEALREADY,
- WSAECONNABORTED,
- WSAECONNREFUSED,
- WSAECONNRESET,
- WSAEDESTADDRREQ,
- WSAEFAULT,
- WSAEHOSTDOWN,
- WSAEHOSTUNREACH,
- WSAEINPROGRESS,
- WSAEINTR,
- WSAEINVAL,
- WSAEISCONN,
- WSAEMFILE,
- WSAEMSGSIZE,
- WSAENETDOWN,
- WSAENETRESET,
- WSAENETUNREACH,
- WSAENOBUFS,
- WSAENOPROTOOPT,
- WSAENOTCONN,
- WSAENOTSOCK,
- WSAEOPNOTSUPP,
- WSAEPFNOSUPPORT,
- WSAEPROCLIM,
- WSAEPROTONOSUPPORT,
- WSAEPROTOTYPE,
- WSAESHUTDOWN,
- WSAESOCKTNOSUPPORT,
- WSAETIMEDOUT,
- WSAEWOULDBLOCK,
- WSAHOST_NOT_FOUND,
- WSANOTINITIALISED,
- WSANO_DATA,
- WSANO_RECOVERY,
- WSASYSNOTREADY,
- WSATRY_AGAIN,
- WSAVERNOTSUPPORTED,
- WSAEDISCON,
- 1001,
- 1002
- };
- static const char lpErrMsgs[][64] =
- {
- "Permission denied.",
- "Address already in use.",
- "Cannot assign requested address.",
- "Address family not supported by protocol family.",
- "Operation already in progress.",
- "Software caused connection abort.",
- "Connection refused.",
- "Connection reset by peer.",
- "Destination address required.",
- "Bad address.",
- "Host is down.",
- "No route to host.",
- "Operation now in progress.",
- "Interrupted function call.",
- "Invalid argument.",
- "Socket is already connected.",
- "Too many open sockets.",
- "Message too long.",
- "Network is down.",
- "Network dropped connection on reset.",
- "Network is unreachable.",
- "No buffer space available.",
- "Bad protocol option.",
- "Socket is not connected.",
- "Socket operation on nonsocket.",
- "Operation not supported.",
- "Protocol family not supported.",
- "Too many processes.",
- "Protocol not supported.",
- "Protocol wrong type for socket.",
- "Cannot send after socket shutdown.",
- "Socket type not supported.",
- "Connection timed out.",
- "Resource temporarily unavailable.",
- "Host not found.",
- "Successful WSAStartup not yet performed.",
- "Valid name, no data record of requested type.",
- "This is a nonrecoverable error.",
- "Network subsystem is unavailable.",
- "Nonauthoritative host not found.",
- "Winsock.dll version out of range.",
- "Graceful shutdown in progress."
- "Mutex not created.",
- "Thread not created."
- };
- for (int i = 0; i < sizeof (lErrCodes) / sizeof (long); i++)
- {
- if (m_number == lErrCodes[i])
- {
- int slen = strlen (lpErrMsgs[i]);
- if (len > slen + 1) len = slen + 1;
- if (str) memcpy (str, lpErrMsgs[i], len);
- return slen;
- }
- }
- char lpUnknown[] = "Unknown error.";
- int slen = strlen (lpUnknown);
- if (len > slen + 1) len = slen + 1;
- if (str) memcpy (str, lpUnknown, len);
- return slen;
- }
- BOOL CConnection::HasConnectionDropped()
- {
- BOOL bConnDropped = FALSE;
- INT iRet = 0;
- BOOL bOK = TRUE;
- if (m_socket == INVALID_SOCKET)
- return TRUE;
- struct timeval timeout = { 0, 0 };
- fd_set readSocketSet;
- FD_ZERO(&readSocketSet);
- FD_SET(m_socket, &readSocketSet);
- iRet = ::select(0, &readSocketSet, NULL, NULL, &timeout);
- bOK = (iRet > 0);
- if(bOK)
- {
- bOK = FD_ISSET(m_socket, &readSocketSet);
- }
- if(bOK)
- {
- CHAR szBuffer[1] = "";
- iRet = ::recv(m_socket, szBuffer, 1, MSG_PEEK);
- bOK = (iRet > 0);
- if(!bOK)
- {
- INT iError = ::WSAGetLastError();
- bConnDropped = (( iError == WSAENETRESET) ||
- (iError == WSAECONNABORTED) ||
- (iError == WSAECONNRESET) ||
- (iError == WSAEINVAL) ||
- (iRet == 0));
- }
- }
- return(bConnDropped);
- }
- void CConnection::SetLastError(long err)
- {
- m_lasterror.m_number = err;
- }
- void CConnection::GetLocalIP(CString &sIP)
- {
- char szHostName[128];
- const char* pszAddr;
- struct hostent * pHost;
- sIP = _T("");
- int i;
- if( gethostname(szHostName, 128) == 0 )
- {
- pHost = gethostbyname(szHostName);
- for( i = 0; pHost!= NULL && pHost->h_addr_list[i]!= NULL; i++ )
- {
- pszAddr=inet_ntoa (*(struct in_addr *)pHost->h_addr_list[i]);
- //printf("%sn",pszAddr);
- sIP += _T(pszAddr);
- sIP += _T(" ");
- }
- }
- }