DWORD CTcpCtrl::Socks5CreateConnection(DWORD dwRemoteAddress, WORD wRemotePort, WORD wLocalPort)
{
// 创建 SOCKET
m_hSock = socket(PF_INET, SOCK_STREAM, 0);
if (INVALID_SOCKET == m_hSock) // 不正确
{
m_hSock = INVALID_SOCKET; 
return RESULT_DWORD_ERROR;
} // 初始化 sockaddr_in 结构
sockaddr_in SockAddr;
SockAddr.sin_family = PF_INET;
SockAddr.sin_addr.s_addr=m_dwProxyIp;
SockAddr.sin_port=htons(m_wProxyPort); // 建立到代理服务器的Tcp连接
int iSocks5Ret=connect(m_hSock,(sockaddr*)&(SockAddr),sizeof(SockAddr));
if(iSocks5Ret != 0)
{
closesocket(m_hSock);
m_hSock=INVALID_SOCKET;
return RESULT_DWORD_ERROR;
}
Socks5SendVer(m_hSock);
char VerBuff[2];
int nVer=recv(m_hSock,VerBuff,2,0);
if((nVer != 2) || (VerBuff[0] != 5))
{
::AfxMessageBox("连接代理服务器时出错!");
closesocket(m_hSock);
m_hSock=INVALID_SOCKET;
return RESULT_DWORD_ERROR;
}
switch(VerBuff[1])
{
case 0:
{
Socks5SendRequestTCP(m_hSock,dwRemoteAddress,wRemotePort);
char RequestBuff[10];
int nRequest=recv(m_hSock,RequestBuff,10,0);
if(  (nRequest != 10) 
   ||(RequestBuff[0] != 5) 
   ||(RequestBuff[1] != 0)  )
{
::AfxMessageBox("连接代理服务器时出错!");
closesocket(m_hSock);
m_hSock=INVALID_SOCKET;
return RESULT_DWORD_ERROR;
}
break;
}
case 2:
{
Socks5SendUserTest(m_hSock);
char TestBuff[2];
int nTest=recv(m_hSock,TestBuff,2,0);
if(  (nTest != 2)
   ||(TestBuff[0] != 5)
   ||(TestBuff[1] != 0)  )
{
::AfxMessageBox("无法通过代理服务器的身份验证,请检查您输入的用户名和密码!");
closesocket(m_hSock);
m_hSock=INVALID_SOCKET;
return RESULT_DWORD_ERROR;
}
Socks5SendRequestTCP(m_hSock,dwRemoteAddress,wRemotePort);
char RequestBuff[10];
int nRequest=recv(m_hSock,RequestBuff,10,0);
if(  (nRequest != 10) 
||(RequestBuff[0] != 5) 
||(RequestBuff[1] != 0)  )
{
::AfxMessageBox("连接代理服务器时出错!");
closesocket(m_hSock);
m_hSock=INVALID_SOCKET;
return RESULT_DWORD_ERROR;
}
break;
}
default:
{
::AfxMessageBox("连接代理服务器时出错!");
closesocket(m_hSock);
m_hSock=INVALID_SOCKET;
return RESULT_DWORD_ERROR;
}
} // 设置socket 为非阻塞
u_long iVal = 1;
int iRet = ioctlsocket(m_hSock, FIONBIO, &iVal);
if (0 != iRet) // 不正确
{
closesocket(m_hSock);
m_hSock = INVALID_SOCKET; 
return RESULT_DWORD_ERROR;
} // 启动线程 调用createthread创建线程
m_bRunning = true; // 设置线程运行标志 为真
DWORD dwThread;
m_hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)(TcpThread), (void*)this, 0, &dwThread);
if(NULL == m_hThread) // m_hThread 如果为0,则线程创建失败
{
closesocket(m_hSock);
m_hSock = INVALID_SOCKET; 
return RESULT_DWORD_ERROR;
} // 赋值给成员变量
m_dwSock = m_pComm->GetSockIndex();     // SOCKET句柄的映射值
m_dwRemoteAddress = m_dwProxyIp;     // 代理服务器的IP地址赋值给成员变量
m_wRemotePort = m_wProxyPort; // 代理服务器的端口号赋值给成员变量
m_iCommType = COMM_TCP;         // 通信协议类型赋值给成员变量
m_iPosType = CLIENT_POS_TYPE; // 通信端所在的位置赋值给成员变量  return m_dwSock;
}

解决方案 »

  1.   

    以上的代码用于通过SOCKS5代理与服务器相互通讯。
    功能已经实现了,但只用lan中的代理进行了测试。想请各位高手给点意见,代码还需要哪些改进。
    主要是超时处理、稳定性等方面。大家随便说说吧,谢谢。
      

  2.   

    http://soft.chsof.com/InfoView/Article_163.html
    http://www.codeproject.com/internet/casyncproxysocket.asp