www.pudn.com > CraftFTP_gb.rar > AsynSocket.cpp
// AsynSocket.cpp: implementation of the CAsynSocket class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "AsynSocket.h"
#include "Base64coding.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
BEGIN_MESSAGE_MAP(CAsynSocket::CSocketWnd, CWnd)
//{{AFX_MSG_MAP(CAsynSocket::CSocketWnd)
ON_MESSAGE(WM_SOCKET_NOTIFY, CAsynSocket::CSocketWnd::OnWinsocketNotify)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CAsynSocket::CSocketWnd::OnWinsocketNotify(WPARAM wParam, LPARAM lParam)
{
if (wParam == 0 && lParam == 0)
return;
int nErrorCode = WSAGETSELECTERROR(lParam);
if(m_bResolved && m_hAsyncGetHostByName == (HANDLE)wParam) //需要解析主机名
{
m_hAsyncGetHostByName = NULL;
m_bResolved = FALSE;
m_pSocket->_OnResolve(nErrorCode);
}
else //已经获取到了主机名,是其他Socket消息
{
if((SOCKET)wParam!=m_pSocket->m_hSocket)
return;
//////////////////////////////////////////////////////////////////
//lParam = 658833440; 在有proxy的环境容易发生此类消息进行过滤
//////////////////////////////////////////////////////////////////
UINT nEvent = WSAGETSELECTEVENT(lParam);
if(nEvent==FD_CLOSE && nErrorCode==WSAECONNABORTED)
return;
switch (nEvent)
{
case FD_READ: //读
{
DWORD nBytes;
if (!m_pSocket->IOCtl(FIONREAD, &nBytes))
nErrorCode = WSAGetLastError();
if (nBytes != 0 || nErrorCode != 0)
m_pSocket->_OnReceive(nErrorCode);
}
break;
case FD_WRITE: //写
m_pSocket->_OnSend(nErrorCode);
break;
case FD_OOB:
m_pSocket->_OnOOBData(nErrorCode);
break;
case FD_ACCEPT: //接收
m_pSocket->_OnAccept(nErrorCode);
break;
case FD_CONNECT: //连接
m_pSocket->_OnConnect(nErrorCode);
break;
case FD_CLOSE: //关闭
m_pSocket->_OnClose(nErrorCode);
break;
default:
break;
}
}
}
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CAsynSocket::CAsynSocket()
{
m_pSocketWnd = NULL;
m_hSocket = INVALID_SOCKET;
memset(&m_szHostBuffer, 0, sizeof(m_szHostBuffer));
m_sockAddr.sin_addr.s_addr = INADDR_NONE;
}
CAsynSocket::~CAsynSocket()
{
}
BOOL CAsynSocket::Create(UINT nSocketPort, int nSocketType, long lEvent, LPCTSTR lpszSocketAddress)
{
m_pSocketWnd = new CSocketWnd(this);
m_pSocketWnd->m_hWnd = NULL;
if (!m_pSocketWnd->CreateEx(0, AfxRegisterWndClass(0),
_T(""), WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL))
{
TRACE0("Warning: unable to create socket notify window!\n");
return FALSE;
}
if (Socket(nSocketType, lEvent))
{
if (Bind(nSocketPort,lpszSocketAddress))
return TRUE;
int nResult = GetLastError();
Close();
WSASetLastError(nResult);
}
return FALSE;
}
BOOL CAsynSocket::ConnectHelper(LPCTSTR lpszHostAddress, UINT nHostPort)
{
ASSERT(lpszHostAddress != NULL);
memset(&m_sockAddr, 0, sizeof(m_sockAddr));
LPSTR lpszAscii = (LPTSTR)lpszHostAddress;
m_sockAddr.sin_family = AF_INET;
m_sockAddr.sin_port = htons((u_short)nHostPort);
m_sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
if(m_pSocketWnd->m_bResolved)
m_pSocketWnd->m_bResolved = FALSE;
if(m_pSocketWnd->m_hAsyncGetHostByName)
{
::WSACancelAsyncRequest(m_pSocketWnd->m_hAsyncGetHostByName);
m_pSocketWnd->m_hAsyncGetHostByName = NULL;
}
if (m_sockAddr.sin_addr.s_addr == INADDR_NONE)
{
m_pSocketWnd->m_bResolved = TRUE;
m_pSocketWnd->m_hAsyncGetHostByName = ::WSAAsyncGetHostByName(m_pSocketWnd->m_hWnd, WM_SOCKET_NOTIFY, lpszAscii, m_szHostBuffer, MAXGETHOSTSTRUCT);
return TRUE;
}
else
{
m_pSocketWnd->m_bResolved = FALSE;
return ConnectHelper((SOCKADDR*)&m_sockAddr, sizeof(m_sockAddr));
}
}
BOOL CAsynSocket::GetPeerName(CString& rPeerAddress, UINT& rPeerPort)
{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
BOOL bResult = GetPeerName((SOCKADDR*)&sockAddr, &nSockAddrLen);
if (bResult)
{
rPeerPort = ntohs(sockAddr.sin_port);
rPeerAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
BOOL CAsynSocket::GetSockName(CString & rSocketAddress, UINT& rSocketPort)
{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
BOOL bResult = GetSockName((SOCKADDR*)&sockAddr, &nSockAddrLen);
if (bResult)
{
rSocketPort = ntohs(sockAddr.sin_port);
rSocketAddress = inet_ntoa(sockAddr.sin_addr);
}
return bResult;
}
void CAsynSocket::Close()
{
//关闭窗口
if(m_pSocketWnd)
{
m_pSocketWnd->DestroyWindow();
delete m_pSocketWnd;
m_pSocketWnd = NULL;
}
//断开连接
if (m_hSocket != INVALID_SOCKET)
{
ShutDown();
VERIFY(SOCKET_ERROR != closesocket(m_hSocket));
m_hSocket = INVALID_SOCKET;
}
}
BOOL CAsynSocket::Socket(int nSocketType, long lEvent, int nProtocolType, int nAddressFormat)
{
ASSERT(m_hSocket == INVALID_SOCKET);
m_hSocket = socket(nAddressFormat,nSocketType,nProtocolType);
if (m_hSocket != INVALID_SOCKET)
return AsyncSelect(lEvent);
return FALSE;
}
BOOL CAsynSocket::AsyncSelect(long lEvent)
{
ASSERT(m_hSocket != INVALID_SOCKET);
return WSAAsyncSelect(m_hSocket, m_pSocketWnd->m_hWnd, WM_SOCKET_NOTIFY, lEvent) != SOCKET_ERROR;
}
BOOL CAsynSocket::Attach(SOCKET hSocket, long lEvent)
{
ASSERT(hSocket != INVALID_SOCKET);
m_hSocket = hSocket;
m_pSocketWnd = new CSocketWnd(this);
m_pSocketWnd->m_hWnd = NULL;
if (!m_pSocketWnd->CreateEx(0, AfxRegisterWndClass(0),
_T(""), WS_OVERLAPPED, 0, 0, 0, 0, NULL, NULL))
{
TRACE0("Warning: unable to create socket notify window!\n");
return FALSE;
}
return AsyncSelect(lEvent);
}
BOOL CAsynSocket::Accept(CAsynSocket & rConnectedSocket, SOCKADDR * lpSockAddr, int* lpSockAddrLen)
{
return TRUE;
}
int CAsynSocket::ReceiveFrom(void* lpBuf, int nBufLen, CString& rSocketAddress, UINT& rSocketPort, int nFlags)
{
SOCKADDR_IN sockAddr;
memset(&sockAddr, 0, sizeof(sockAddr));
int nSockAddrLen = sizeof(sockAddr);
int nResult = ReceiveFrom(lpBuf, nBufLen, (SOCKADDR*)&sockAddr, &nSockAddrLen, nFlags);
if(nResult != SOCKET_ERROR)
{
rSocketPort = ntohs(sockAddr.sin_port);
rSocketAddress = inet_ntoa(sockAddr.sin_addr);
}
return nResult;
}
int CAsynSocket::SendTo(const void* lpBuf, int nBufLen, UINT nHostPort, LPCTSTR lpszHostAddress, int nFlags)
{
//USES_CONVERSION;
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
//LPSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
LPSTR lpszAscii = (LPTSTR)lpszHostAddress;
sockAddr.sin_family = AF_INET;
if (lpszAscii == NULL)
sockAddr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
else
{
sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
if (sockAddr.sin_addr.s_addr == INADDR_NONE)
{
LPHOSTENT lphost;
lphost = gethostbyname(lpszAscii);
if (lphost != NULL)
sockAddr.sin_addr.s_addr = ((LPIN_ADDR)lphost->h_addr)->s_addr;
else
{
WSASetLastError(WSAEINVAL);
return SOCKET_ERROR;
}
}
}
sockAddr.sin_port = htons((u_short)nHostPort);
return SendTo(lpBuf, nBufLen, (SOCKADDR*)&sockAddr, sizeof(sockAddr), nFlags);
}
BOOL CAsynSocket::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
{
//USES_CONVERSION;
SOCKADDR_IN sockAddr;
memset(&sockAddr,0,sizeof(sockAddr));
//LPSTR lpszAscii = T2A((LPTSTR)lpszSocketAddress);
LPSTR lpszAscii = (LPTSTR)lpszSocketAddress;
sockAddr.sin_family = AF_INET;
if (lpszAscii == NULL)
sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
else
{
DWORD lResult = inet_addr(lpszAscii);
if (lResult == INADDR_NONE)
{
WSASetLastError(WSAEINVAL);
return FALSE;
}
sockAddr.sin_addr.s_addr = lResult;
}
sockAddr.sin_port = htons((u_short)nSocketPort);
return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
}
void CAsynSocket::_OnResolve(int nErrorCode)
{
if(nErrorCode == 0)
{
hostent * he = (hostent*)m_szHostBuffer;
m_sockAddr.sin_addr.s_addr = *((u_long*)he->h_addr_list[0]);
memset(&m_szHostBuffer, 0, sizeof(m_szHostBuffer));
}
else
WSASetLastError(WSAEINVAL);
OnResolve(nErrorCode);
}
void CAsynSocket::_OnConnect(int nErrorCode)
{
OnConnect(nErrorCode);
}
void CAsynSocket::_OnClose(int nErrorCode)
{
AsyncSelect(0);
if(m_pSocketWnd)
{
m_pSocketWnd->DestroyWindow();
delete m_pSocketWnd;
m_pSocketWnd = NULL;
}
OnClose(nErrorCode);
}
void CAsynSocket::_OnAccept(int nErrorCode)
{
OnAccept(nErrorCode);
}
void CAsynSocket::_OnReceive(int nErrorCode)
{
OnReceive(nErrorCode);
}
void CAsynSocket::_OnSend(int nErrorCode)
{
OnSend(nErrorCode);
}
void CAsynSocket::_OnAttach()
{
OnAttach();
}
void CAsynSocket::_OnOOBData(int nErrorCode)
{
OnOOBData(nErrorCode);
}
void CAsynSocket::OnResolve(int nErrorCode)
{
}
void CAsynSocket::OnConnect(int nErrorCode)
{
}
void CAsynSocket::OnClose(int nErrorCode)
{
}
void CAsynSocket::OnAccept(int nErrorCode)
{
}
void CAsynSocket::OnReceive(int nErrorCode)
{
}
void CAsynSocket::OnSend(int nErrorCode)
{
}
void CAsynSocket::OnAttach()
{
}
void CAsynSocket::OnClear()
{
}
void CAsynSocket::OnOOBData(int nErrorCode)
{
}
BOOL CAsynSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
return ConnectHelper(lpszHostAddress, nHostPort);
}
BOOL CAsynSocket::Connect(const SOCKADDR * lpSockAddr, int nSockAddrLen)
{
return ::connect(m_hSocket, lpSockAddr, nSockAddrLen);
}
BOOL CAsynSocket::Connect()
{ return ConnectHelper((SOCKADDR*)&m_sockAddr, sizeof(m_sockAddr)); }
BOOL CAsynSocket::ConnectHelper(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{
return Connect(lpSockAddr, nSockAddrLen);
}
int CAsynSocket::SendTo(const void* lpBuf, int nBufLen, const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags)
{ return ::sendto(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, nSockAddrLen); }
int CAsynSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
{ return ::send(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags); }
int CAsynSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
{ return ::recv(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags); }
BOOL CAsynSocket::Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen)
{ return (SOCKET_ERROR != ::bind(m_hSocket, lpSockAddr, nSockAddrLen)); }
BOOL CAsynSocket::Listen(int nConnectionBacklog)
{ return (SOCKET_ERROR != ::listen(m_hSocket, nConnectionBacklog)); }
BOOL CAsynSocket::GetPeerName(SOCKADDR* lpSockAddr, int* lpSockAddrLen)
{ return (SOCKET_ERROR != ::getpeername(m_hSocket, lpSockAddr, lpSockAddrLen)); }
BOOL CAsynSocket::GetSockName(SOCKADDR* lpSockAddr, int* lpSockAddrLen)
{ return (SOCKET_ERROR != ::getsockname(m_hSocket, lpSockAddr, lpSockAddrLen)); }
BOOL CAsynSocket::GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel)
{ return (SOCKET_ERROR != ::getsockopt(m_hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen)); }
BOOL CAsynSocket::SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel)
{ return (SOCKET_ERROR != ::setsockopt(m_hSocket, nLevel, nOptionName, (LPCSTR)lpOptionValue, nOptionLen)); }
BOOL CAsynSocket::IOCtl(long lCommand, DWORD* lpArgument)
{ return (SOCKET_ERROR != ::ioctlsocket(m_hSocket, lCommand, lpArgument)); }
int CAsynSocket::ReceiveFrom(void* lpBuf, int nBufLen, SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags)
{ return ::recvfrom(m_hSocket, (LPSTR)lpBuf, nBufLen, nFlags, lpSockAddr, lpSockAddrLen); }
BOOL CAsynSocket::ShutDown(int nHow)
{ return (SOCKET_ERROR != ::shutdown(m_hSocket,nHow)); }