//连接操作
BYTE CWEBSocket::ConnectServer(LPCTSTR pszServer, WORD wPort)
{
//效验参数
ASSERT(m_hSocket==INVALID_SOCKET);
ASSERT(m_cbSocketStatus==SOCKET_STATUS_IDLE);
//设置参数
m_wHeadSize=0;
ZeroMemory(m_szHeadData,sizeof(m_szHeadData));
//转化地址
CT2CA HttpServer(pszServer);
DWORD dwServerIP=inet_addr(HttpServer);
//域名解释
if (dwServerIP==INADDR_NONE)
{
LPHOSTENT lpHost=gethostbyname(HttpServer);
if (lpHost!=NULL) dwServerIP=((LPIN_ADDR)lpHost->h_addr)->s_addr;
}
try
{
//建立 SOCKET
m_hSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (m_hSocket==INVALID_SOCKET) throw CONNECT_EXCEPTION;
//创建窗口
if (m_hWnd==NULL)
{
CRect rcSocketWnd;
Create(NULL,NULL,WS_CHILD,rcSocketWnd,GetDesktopWindow(),100);
}
//变量定义
SOCKADDR_IN SocketAddr;
ZeroMemory(&SocketAddr,sizeof(SocketAddr));
//设置变量
SocketAddr.sin_family=AF_INET;
SocketAddr.sin_port=htons(wPort);
SocketAddr.sin_addr.S_un.S_addr=dwServerIP;
//代理连接
if (m_cbProxyType!=PROXY_NONE)
{
//连接代理
DWORD dwResult=ConnectProxyServer();
if (dwResult!=CONNECT_SUCCESS) throw dwResult;
//请求连接
switch (m_cbProxyType)
{
case PROXY_HTTP: //HTTP 代理
{
//构造请求
char cbDataBuffer[512];
BYTE * pcbServerIP=(BYTE *)&dwServerIP;
_snprintf(cbDataBuffer,CountArray(cbDataBuffer),"CONNECT %d.%d.%d.%d:%d HTTP/1.0\r\nUser-Agent: WHPlatform/0.1\r\n\r\n",
pcbServerIP[0],pcbServerIP[1],pcbServerIP[2],pcbServerIP[3],wPort);
//连接请求
INT nRequestLen=(INT)strlen(cbDataBuffer);
if (send(m_hSocket,cbDataBuffer,nRequestLen,0)!=nRequestLen) throw CONNECT_PROXY_FAILURE;
//接收响应
INT nRecvCount=recv(m_hSocket,cbDataBuffer,sizeof(cbDataBuffer),0);
if (nRecvCount>0) cbDataBuffer[nRecvCount]=0;
//结果判断
bool bSuccess=false;
for (INT i=0;i<nRecvCount;i++)
{
if ((cbDataBuffer[i]==' ')&&(cbDataBuffer[i+1]=='2')&&(cbDataBuffer[i+2]=='0')&&(cbDataBuffer[i+3]=='0'))
{
bSuccess=true;
break;
}
}
//结果判断
if (bSuccess==false) throw CONNECT_PROXY_FAILURE;
break;
}
case PROXY_SOCKS5: //Socks5 代理
{
//构造请求
INT nOff=4;
char cbDataBuffer[256]={5,1,0,1};
//连接地址
CopyMemory(cbDataBuffer+nOff,&SocketAddr.sin_addr,sizeof(SocketAddr.sin_addr));
nOff+=sizeof(SocketAddr.sin_addr);
//连接端口
*(WORD*)(cbDataBuffer+nOff)=SocketAddr.sin_port;
nOff+=sizeof(WORD);
//连接请求
if (send(m_hSocket,cbDataBuffer,nOff,0)!=nOff) throw CONNECT_PROXY_FAILURE;
//接收响应
INT nRecvCount=recv(m_hSocket,cbDataBuffer,4,0);
if (nRecvCount!=4) throw CONNECT_PROXY_FAILURE;
if (cbDataBuffer[0]!=5) throw CONNECT_PROXY_FAILURE;
//失败判断
if (cbDataBuffer[1]==0) throw CONNECT_PROXY_FAILURE;
//接收数据
INT nLeftDataLen=(cbDataBuffer[3]==1)?6:cbDataBuffer[4]+2;
if (recv(m_hSocket,cbDataBuffer,nLeftDataLen,0)!=nLeftDataLen) throw CONNECT_PROXY_FAILURE;
break;
}
case PROXY_SOCKS4: //Socks4 代理
{
//构造请求
INT nOff=2;
char cbDataBuffer[256]={4,1};
//连接端口
*(WORD*)(cbDataBuffer+nOff)=SocketAddr.sin_port;
nOff+=sizeof(WORD);
//连接地址
CopyMemory(cbDataBuffer+nOff,&SocketAddr.sin_addr,sizeof(SocketAddr.sin_addr));
nOff+=sizeof(SocketAddr.sin_addr);
//保留字段
cbDataBuffer[nOff++]=0;
//连接请求
INT nResult=send(m_hSocket,cbDataBuffer,nOff,0);
if (nResult!=nOff) throw CONNECT_PROXY_FAILURE;
//接收响应
nResult=recv(m_hSocket,cbDataBuffer,8,0);
if (nResult!=8) throw CONNECT_PROXY_FAILURE;
if (cbDataBuffer[0]!=0) throw CONNECT_PROXY_FAILURE;
//失败判断
if (cbDataBuffer[1]!=90) throw CONNECT_PROXY_FAILURE;
break;
}
default: //默认处理
{
ASSERT(FALSE);
throw CONNECT_PROXY_FAILURE;
}
}
//连接成功
WSASetLastError(0);
//设置变量
m_cbSocketStatus=SOCKET_STATUS_CONNECT;
//发送消息
PostMessage(WM_SOCKET_NOTIFY,0,MAKELONG(FD_CONNECT,0));
//绑定窗口
WSAAsyncSelect(m_hSocket,m_hWnd,WM_SOCKET_NOTIFY,FD_READ|FD_CONNECT|FD_CLOSE|FD_WRITE);
}
else
{
//绑定窗口
WSAAsyncSelect(m_hSocket,m_hWnd,WM_SOCKET_NOTIFY,FD_READ|FD_CONNECT|FD_CLOSE|FD_WRITE);
//发起连接
INT nErrorCode=connect(m_hSocket,(SOCKADDR *)&SocketAddr,sizeof(SocketAddr));
if ((nErrorCode==SOCKET_ERROR)&&(WSAGetLastError()!=WSAEWOULDBLOCK)) throw CONNECT_EXCEPTION;
//设置变量
m_cbSocketStatus=SOCKET_STATUS_WAIT;
}
}
catch (...)
{
//关闭连接
CloseSocket(SHUT_REASON_INSIDE);
return CONNECT_EXCEPTION;
}
return CONNECT_SUCCESS;
}
BYTE CWEBSocket::ConnectServer(LPCTSTR pszServer, WORD wPort)
{
//效验参数
ASSERT(m_hSocket==INVALID_SOCKET);
ASSERT(m_cbSocketStatus==SOCKET_STATUS_IDLE);
//设置参数
m_wHeadSize=0;
ZeroMemory(m_szHeadData,sizeof(m_szHeadData));
//转化地址
CT2CA HttpServer(pszServer);
DWORD dwServerIP=inet_addr(HttpServer);
//域名解释
if (dwServerIP==INADDR_NONE)
{
LPHOSTENT lpHost=gethostbyname(HttpServer);
if (lpHost!=NULL) dwServerIP=((LPIN_ADDR)lpHost->h_addr)->s_addr;
}
try
{
//建立 SOCKET
m_hSocket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if (m_hSocket==INVALID_SOCKET) throw CONNECT_EXCEPTION;
//创建窗口
if (m_hWnd==NULL)
{
CRect rcSocketWnd;
Create(NULL,NULL,WS_CHILD,rcSocketWnd,GetDesktopWindow(),100);
}
//变量定义
SOCKADDR_IN SocketAddr;
ZeroMemory(&SocketAddr,sizeof(SocketAddr));
//设置变量
SocketAddr.sin_family=AF_INET;
SocketAddr.sin_port=htons(wPort);
SocketAddr.sin_addr.S_un.S_addr=dwServerIP;
//代理连接
if (m_cbProxyType!=PROXY_NONE)
{
//连接代理
DWORD dwResult=ConnectProxyServer();
if (dwResult!=CONNECT_SUCCESS) throw dwResult;
//请求连接
switch (m_cbProxyType)
{
case PROXY_HTTP: //HTTP 代理
{
//构造请求
char cbDataBuffer[512];
BYTE * pcbServerIP=(BYTE *)&dwServerIP;
_snprintf(cbDataBuffer,CountArray(cbDataBuffer),"CONNECT %d.%d.%d.%d:%d HTTP/1.0\r\nUser-Agent: WHPlatform/0.1\r\n\r\n",
pcbServerIP[0],pcbServerIP[1],pcbServerIP[2],pcbServerIP[3],wPort);
//连接请求
INT nRequestLen=(INT)strlen(cbDataBuffer);
if (send(m_hSocket,cbDataBuffer,nRequestLen,0)!=nRequestLen) throw CONNECT_PROXY_FAILURE;
//接收响应
INT nRecvCount=recv(m_hSocket,cbDataBuffer,sizeof(cbDataBuffer),0);
if (nRecvCount>0) cbDataBuffer[nRecvCount]=0;
//结果判断
bool bSuccess=false;
for (INT i=0;i<nRecvCount;i++)
{
if ((cbDataBuffer[i]==' ')&&(cbDataBuffer[i+1]=='2')&&(cbDataBuffer[i+2]=='0')&&(cbDataBuffer[i+3]=='0'))
{
bSuccess=true;
break;
}
}
//结果判断
if (bSuccess==false) throw CONNECT_PROXY_FAILURE;
break;
}
case PROXY_SOCKS5: //Socks5 代理
{
//构造请求
INT nOff=4;
char cbDataBuffer[256]={5,1,0,1};
//连接地址
CopyMemory(cbDataBuffer+nOff,&SocketAddr.sin_addr,sizeof(SocketAddr.sin_addr));
nOff+=sizeof(SocketAddr.sin_addr);
//连接端口
*(WORD*)(cbDataBuffer+nOff)=SocketAddr.sin_port;
nOff+=sizeof(WORD);
//连接请求
if (send(m_hSocket,cbDataBuffer,nOff,0)!=nOff) throw CONNECT_PROXY_FAILURE;
//接收响应
INT nRecvCount=recv(m_hSocket,cbDataBuffer,4,0);
if (nRecvCount!=4) throw CONNECT_PROXY_FAILURE;
if (cbDataBuffer[0]!=5) throw CONNECT_PROXY_FAILURE;
//失败判断
if (cbDataBuffer[1]==0) throw CONNECT_PROXY_FAILURE;
//接收数据
INT nLeftDataLen=(cbDataBuffer[3]==1)?6:cbDataBuffer[4]+2;
if (recv(m_hSocket,cbDataBuffer,nLeftDataLen,0)!=nLeftDataLen) throw CONNECT_PROXY_FAILURE;
break;
}
case PROXY_SOCKS4: //Socks4 代理
{
//构造请求
INT nOff=2;
char cbDataBuffer[256]={4,1};
//连接端口
*(WORD*)(cbDataBuffer+nOff)=SocketAddr.sin_port;
nOff+=sizeof(WORD);
//连接地址
CopyMemory(cbDataBuffer+nOff,&SocketAddr.sin_addr,sizeof(SocketAddr.sin_addr));
nOff+=sizeof(SocketAddr.sin_addr);
//保留字段
cbDataBuffer[nOff++]=0;
//连接请求
INT nResult=send(m_hSocket,cbDataBuffer,nOff,0);
if (nResult!=nOff) throw CONNECT_PROXY_FAILURE;
//接收响应
nResult=recv(m_hSocket,cbDataBuffer,8,0);
if (nResult!=8) throw CONNECT_PROXY_FAILURE;
if (cbDataBuffer[0]!=0) throw CONNECT_PROXY_FAILURE;
//失败判断
if (cbDataBuffer[1]!=90) throw CONNECT_PROXY_FAILURE;
break;
}
default: //默认处理
{
ASSERT(FALSE);
throw CONNECT_PROXY_FAILURE;
}
}
//连接成功
WSASetLastError(0);
//设置变量
m_cbSocketStatus=SOCKET_STATUS_CONNECT;
//发送消息
PostMessage(WM_SOCKET_NOTIFY,0,MAKELONG(FD_CONNECT,0));
//绑定窗口
WSAAsyncSelect(m_hSocket,m_hWnd,WM_SOCKET_NOTIFY,FD_READ|FD_CONNECT|FD_CLOSE|FD_WRITE);
}
else
{
//绑定窗口
WSAAsyncSelect(m_hSocket,m_hWnd,WM_SOCKET_NOTIFY,FD_READ|FD_CONNECT|FD_CLOSE|FD_WRITE);
//发起连接
INT nErrorCode=connect(m_hSocket,(SOCKADDR *)&SocketAddr,sizeof(SocketAddr));
if ((nErrorCode==SOCKET_ERROR)&&(WSAGetLastError()!=WSAEWOULDBLOCK)) throw CONNECT_EXCEPTION;
//设置变量
m_cbSocketStatus=SOCKET_STATUS_WAIT;
}
}
catch (...)
{
//关闭连接
CloseSocket(SHUT_REASON_INSIDE);
return CONNECT_EXCEPTION;
}
return CONNECT_SUCCESS;
}