一些代理的连接方法:socks4,socks5,https,http

sevencat 2003-11-13 02:48:41
框架。
http://www.socks.nec.com/protocol/socks4.protocol
http://www.socks.nec.com/protocol/socks4a.protocol
//里面的原代码均是选自于miranda32这个开源项目中的。
//代理服务器的代码推荐大家去学习oops-1.5.22里面的,这也是个开源项目。

int NetlibOpenConnection(WPARAM wParam,LPARAM lParam)
{
NETLIBOPENCONNECTION *nloc=(NETLIBOPENCONNECTION*)lParam;
struct NetlibUser *nlu=(struct NetlibUser*)wParam;
struct NetlibConnection *nlc;
SOCKADDR_IN sin;

if(GetNetlibHandleType(nlu)!=NLH_USER || !(nlu->user.flags&NUF_OUTGOING) || nloc==NULL || nloc->cbSize!=sizeof(NETLIBOPENCONNECTION) || nloc->szHost==NULL || nloc->wPort==0)
{
SetLastError(ERROR_INVALID_PARAMETER);
return (int)(HANDLE)NULL;
}
nlc=(struct NetlibConnection*)calloc(1,sizeof(struct NetlibConnection));
nlc->handleType=NLH_CONNECTION;
nlc->nlu=nlu;
nlc->s=socket(AF_INET,SOCK_STREAM,0);
if(nlc->s==INVALID_SOCKET)
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"socket",WSAGetLastError());
free(nlc);
return (int)(HANDLE)NULL;
}
if (nlu->settings.szIncomingPorts)
{
BYTE portsMask[0x2000];
int startPort,portNum,i,j,portsCount;

sin.sin_family=AF_INET;
sin.sin_addr.s_addr=htonl(INADDR_ANY);
sin.sin_port=0;

portsCount=StringToPortsMask(nlu->settings.szIncomingPorts,portsMask);
if (portsCount)
{
startPort=rand()&portsCount;
for (i=0;i<0x02000;i++)
{
if(portsMask[i]==0) continue;
if(portsMask[i]==0xFF && startPort>=8) {startPort-=8; continue;}
for(j=0;j<8;j++)
if(portsMask[i]&(1<<j))
if(startPort--==0)
{
portNum=(i<<3)+j;
break;
}
if(startPort==-1) break;
} //for
if (i!=0x2000)
{
startPort=portNum;
do
{
sin.sin_port=htons((WORD)portNum);
if(bind(nlc->s,(SOCKADDR*)&sin,sizeof(sin))==0) break;
for(portNum++;!PortInMask(portsMask,portNum);portNum++)
if(portNum==0xFFFF) portNum=0;
} while (portNum!=startPort);
} //if
} //if
}
InitializeCriticalSection(&nlc->csHttpSequenceNums);
nlc->hOkToCloseEvent=CreateEvent(NULL,TRUE,TRUE,NULL);
nlc->dontCloseNow=0;
NetlibInitializeNestedCS(&nlc->ncsSend);
NetlibInitializeNestedCS(&nlc->ncsRecv);
if(nlu->settings.useProxy && (nlu->settings.proxyType==PROXYTYPE_HTTP || nlu->settings.proxyType==PROXYTYPE_HTTPS) && nlu->settings.useProxyAuth && nlu->settings.useProxyAuthNtlm)
nlc->hInstSecurityDll=LoadLibrary("security.dll");

nlc->sinProxy.sin_family=AF_INET;
if(nlu->settings.useProxy)
{
nlc->sinProxy.sin_port=htons((short)nlu->settings.wProxyPort);
nlc->sinProxy.sin_addr.S_un.S_addr=DnsLookup(nlu,nlu->settings.szProxyServer);
}
else
{
nlc->sinProxy.sin_port=htons((short)nloc->wPort);
nlc->sinProxy.sin_addr.S_un.S_addr=DnsLookup(nlu,nloc->szHost);
}
if(nlc->sinProxy.sin_addr.S_un.S_addr==0
|| connect(nlc->s,(SOCKADDR *)&nlc->sinProxy,sizeof(nlc->sinProxy))==SOCKET_ERROR)
{
if(nlc->sinProxy.sin_addr.S_un.S_addr)
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"connect",WSAGetLastError());
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}

if(nlu->settings.useProxy
&& !(nloc->flags&NLOCF_HTTP
&& (nlu->settings.proxyType==PROXYTYPE_HTTP || nlu->settings.proxyType==PROXYTYPE_HTTPS)))
{
if(!WaitUntilWritable(nlc->s,30000))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}

switch(nlu->settings.proxyType)
{
case PROXYTYPE_SOCKS4:
//socks4代理的连接,直接调用NetlibInitSocks4Connection
if(!NetlibInitSocks4Connection(nlc,nlu,nloc))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
break;

case PROXYTYPE_SOCKS5:
//socks5代理的连接,直接调用NetlibInitSocks5Connection
if(!NetlibInitSocks5Connection(nlc,nlu,nloc))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
break;

case PROXYTYPE_HTTPS:
//https代理连接,直接调用NetlibInitHttpsConnection
if(!NetlibInitHttpsConnection(nlc,nlu,nloc))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
break;

case PROXYTYPE_HTTP:
//http代理连接
if(!(nlu->user.flags&NUF_HTTPGATEWAY))
{
//NLOCF_HTTP not specified and no HTTP gateway available: try HTTPS
if(!NetlibInitHttpsConnection(nlc,nlu,nloc))
{
//can't do HTTPS: try direct
if(nlc->s!=INVALID_SOCKET) closesocket(nlc->s);

nlc->s=socket(AF_INET,SOCK_STREAM,0);
if(nlc->s==INVALID_SOCKET)
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
nlc->sinProxy.sin_family=AF_INET;
nlc->sinProxy.sin_port=htons((short)nloc->wPort);
nlc->sinProxy.sin_addr.S_un.S_addr=DnsLookup(nlu,nloc->szHost);
if(nlc->sinProxy.sin_addr.S_un.S_addr==0
|| connect(nlc->s,(SOCKADDR *)&nlc->sinProxy,sizeof(nlc->sinProxy))==SOCKET_ERROR)
{
if(nlc->sinProxy.sin_addr.S_un.S_addr)
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"connect",WSAGetLastError());
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
}
}
else if(!NetlibInitHttpConnection(nlc,nlu,nloc))
{
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
break;

default:
SetLastError(ERROR_INVALID_PARAMETER);
FreePartiallyInitedConnection(nlc);
return (int)(HANDLE)NULL;
}
}
Netlib_Logf(nlu,"(%d) Connected to %s:%d",nlc->s,nloc->szHost,nloc->wPort);
return (int)nlc;
}
...全文
1187 点赞 收藏 11
写回复
11 条回复
xiaochai123 2004年03月03日
up
回复 点赞
ZHENG017 2004年03月03日
http代理不是转发的http数据包。连接到http代理的3128(squid服务器)端口后发送
"CONNECT %s:%d HTTP/1.1\r\n", m_ServerIP, m_nServerPort
回复 点赞
Cowboy22 2003年11月14日
int CDSocket::Receive(void* lpBuf, int nBufLen, int nFlags)
{
// TODO: Add your specialized code here and/or call the base class
int nLen;
if ( !m_prbf )
return 0;
nLen = m_prbf->Receive(lpBuf, nBufLen);

return nLen;
}

void CDSocket::Close()
{
TRACE("Close;\n");
CAsyncSocket::Close();
CleanLst();
if ( m_pSession && m_pSession->IsConnected() )
m_pSession->OnClose();
}

BOOL CDSocket::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
{
m_bProxyPassed = FALSE;
m_ServerIP = lpszHostAddress;
m_nServerPort = nHostPort;
if ( m_ProxyType == PROXY_NONE )
// directly connect to the server
return CAsyncSocket::Connect(lpszHostAddress, nHostPort);
else
// connect to the proxy server instead.
return CAsyncSocket::Connect(m_ProxyIP, m_nProxyPort);
}

int CDSocket::GetRecvBufSize()
{
if ( m_prbf )
return m_prbf->GetBufSize();

return 0;
}

void CDSocket::CleanLst()
{
TSendBuf *ts;
while ( m_pHead != NULL ) {
ts = m_pHead;
m_pHead = m_pHead->pNext;
if ( ts->pBuf )
delete [] ts->pBuf;
delete ts;
}
m_pHead = m_pTail = NULL;
}

__int64 CDSocket::GetTotalSent()
{
return m_iSent;
}

__int64 CDSocket::GetTotalReceived()
{
return m_iReceived;
}

void CDSocket::SetProxySetting(TProxyType ProxyType, CString strProxyIP, int nProxyPort,
BOOL bUserVerify, char *ProxyUser, char *ProxyPwd)
{
m_ProxyType = ProxyType;
m_bUserVerify = bUserVerify;
m_ProxyIP = strProxyIP;
m_ProxyUser = ProxyUser;
m_ProxyPwd = ProxyPwd;
m_nProxyPort = nProxyPort;
}

TProxyType CDSocket::_ProxyOnConnect()
{
switch ( m_ProxyType ) {
case PROXY_HTTP:
_HttpProxyOnConnect();
break;
case PROXY_SOCKS4:
_Socks4ProxyOnConnect();
break;
case PROXY_SOCKS5:
_Socks5ProxyOnConnect();
break;
case PROXY_NONE:
default:
return PROXY_NONE;
}
return m_ProxyType;
}

void CDSocket::_HttpProxyOnConnect()
{
CString strConnect ;
if ( m_bUserVerify ) {
strConnect.Format("CONNECT %s:%d HTTP/1.1\r\n", m_ServerIP, m_nServerPort);
CString strUserPassword;
strUserPassword.Format("%s:%s", m_ProxyUser, m_ProxyPwd);
CByteArray array;
for(int i = 0; i<strUserPassword.GetLength(); i++)
array.Add(strUserPassword[i]);
CString strBase64;
CBase64Coding base64;
base64.Encode(array, strBase64);
strConnect +="Proxy-Authorization: Basic "+strBase64+"\r\n\r\n";
}
else
strConnect.Format("CONNECT %s:%d HTTP/1.1\r\nUser-Agent: MyApp/0.1\r\n\r\n", m_ServerIP, m_nServerPort);

Send(strConnect, strConnect.GetLength());
}

void CDSocket::_Socks4ProxyOnConnect()
{
sock4req1 sock4;
sock4.VN = 4;
sock4.CD = 1;
sock4.Port = ntohs(m_nServerPort);
sock4.IPAddr = inet_addr(m_ServerIP);
Send(&sock4, sizeof(sock4req1));
}

void CDSocket::_Socks5ProxyOnConnect()
{
sock5req1 socks5;
socks5.Ver = 5;
socks5.nMethods = 2;
socks5.Methods[0] = 0;
socks5.Methods[1] = 2;
Send(&socks5,sizeof(sock5req1));
m_socks5step = 0;
}

TProxyType CDSocket::_ProxyOnReceive()
{
switch ( m_ProxyType ) {
case PROXY_HTTP:
_HttpProxyOnReceive();
break;
case PROXY_SOCKS4:
_Socks4ProxyOnReceive();
break;
case PROXY_SOCKS5:
_Socks5ProxyOnReceive();
break;
case PROXY_NONE:
default:
return PROXY_NONE;
}

return m_ProxyType;
}

void CDSocket::_HttpProxyOnReceive()
{
int nLen;
char *pBuf;

if ( (nLen=GetRecvBufSize()) < 1 )
return;
else {
pBuf = new char [nLen+1];
if ( pBuf ) {
Receive(pBuf, nLen);
pBuf[nLen-1] = '\0';
if ( strchr(pBuf, '\n' ) ) {
if ( strstr(pBuf, HTTPPROXY_VERIFY) != NULL ) {
m_bProxyPassed = TRUE;
if ( m_pSession )
m_pSession->OnConnect(0);
}
else
Close();
}
else {
Add2Buf(pBuf, nLen);
}

delete []pBuf;
}
else
Close();
}
}

void CDSocket::_Socks4ProxyOnReceive()
{
int nLen, nSock4;
char buff[16];
sock4ans1 *socks4;

nSock4 = 8;

memset(buff, 0, 16);
if ( (nLen=GetRecvBufSize()) < nSock4 )
return;
socks4 = (sock4ans1 *)buff;
nLen = Receive(buff,nLen);
if(socks4->VN != 0 || socks4->CD != 90)
Close();
else {
m_bProxyPassed = TRUE;
if ( m_pSession )
m_pSession->OnConnect(0);
}
}

void CDSocket::_Socks5ProxyOnReceive()
{
int nLen;
char buff[600];
memset(buff, 0, 100);

if ( m_socks5step == 0 ) {
sock5ans1 *s5ans;
int ns5Step0=2;
s5ans = (sock5ans1 *)buff;
if ( (nLen=GetRecvBufSize()) < ns5Step0 )
return;
Receive(buff,nLen);
if( s5ans->Ver != 5 || (s5ans->Method!=0 && s5ans->Method!=2) ) {
Close();
return;
}
if( s5ans->Method == 2 ) {
authreq *s5authreq;
s5authreq = (struct authreq *)buff;
s5authreq->Ver = 1;
s5authreq->Ulen = m_ProxyUser.GetLength();
strcpy(s5authreq->Name, m_ProxyUser);
s5authreq->PLen = m_ProxyPwd.GetLength();
strcpy(s5authreq->Pass, m_ProxyPwd);
Send(buff,513);
m_socks5step = 1;
}
else {
sock5req2 *ps5 = (sock5req2 *)buff;
ps5->Ver = 5;
ps5->Cmd = 1;
ps5->Rsv = 0;
ps5->Atyp = 1;
unsigned long tmpLong = inet_addr(m_ServerIP);
unsigned short port = ntohs(m_nServerPort);
memcpy(ps5->other,&tmpLong,4);
memcpy(ps5->other+4,&port,2);
Send(buff,sizeof(sock5req2)+5);
m_socks5step = 2;
}
}
else
if ( m_socks5step == 1 ) {
authans *m_authans;
int ns5Step1=10;
m_authans = (authans *)buff;
// if ( (nLen=GetRecvBufSize()) < ns5Step0 )
// return;
nLen = Receive(buff,600);
if( m_authans->Ver != 1 || m_authans->Status != 0 ) {
// "代理服务器用户验证不成功!"
Close();
return;
}
memset(buff, 0, 100);
sock5req2 *m_proxyreq2;
m_proxyreq2 = (sock5req2 *)buff;
m_proxyreq2->Ver = 5;
m_proxyreq2->Cmd = 1;
m_proxyreq2->Rsv = 0;
m_proxyreq2->Atyp = 1;
unsigned long tmpLong = inet_addr(m_ServerIP);
unsigned short port = ntohs(m_nServerPort);
memcpy(m_proxyreq2->other,&tmpLong,4);
memcpy(m_proxyreq2->other+4,&port,2);
Send(buff,sizeof(sock5req2)+5);
m_socks5step = 2;
}
else
if ( m_socks5step == 2 ) {
sock5ans2 *m_proxyans2;
int ns5Step2=10;
m_proxyans2 = (sock5ans2 *)buff;
if ( (nLen=GetRecvBufSize()) < ns5Step2 )
return;
Receive(buff,nLen);
if(m_proxyans2->Ver != 5 || m_proxyans2->Rep != 0) {
//"通过代理连接主站不成功!"
Close();
}
m_bProxyPassed = TRUE;
if ( m_pSession )
m_pSession->OnConnect(0);
}
}
回复 点赞
Cowboy22 2003年11月14日
// DSocket.cpp : implementation file
//

#include "stdafx.h"
#include "DSocket.h"
#include "CBase64Coding.h"
#include "session.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#ifndef TRACE
#define TRACE TRACE
#endif

CDSocket *pDSocket;
/////////////////////////////////////////////////////////////////////////////
// CDSocket

CDSocket::CDSocket(CSession *pSession)
{
m_prbf = NULL;
m_pSession = pSession;
m_bProxyPassed = TRUE;
m_ProxyType = PROXY_NONE;
m_pHead = m_pTail = NULL;
m_bConnected = FALSE;
pDSocket = this;
}

CDSocket::~CDSocket()
{
CleanLst();
if ( m_prbf )
delete m_prbf;
}

// Do not edit the following lines, which are needed by ClassWizard.
#if 0
BEGIN_MESSAGE_MAP(CDSocket, CAsyncSocket)
//{{AFX_MSG_MAP(CDSocket)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
#endif // 0

/////////////////////////////////////////////////////////////////////////////
// CDSocket member functions

void CDSocket::OnConnect(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
TRACE("CDSocket::OnConnect\n");
CleanLst();
if ( m_prbf )
delete m_prbf;
if (0 != nErrorCode)
{
switch( nErrorCode )
{
case WSAEADDRINUSE:
//AfxMessageBox("The specified address is already in use.\n");
break;
case WSAEADDRNOTAVAIL:
//AfxMessageBox("The specified address is not available from the local machine.\n");
break;
case WSAEAFNOSUPPORT:
//AfxMessageBox("Addresses in the specified family cannot be used with this socket.\n");
break;
case WSAECONNREFUSED:
//AfxMessageBox("The attempt to connect was forcefully rejected.\n");
break;
case WSAEDESTADDRREQ:
//AfxMessageBox("A destination address is required.\n");
break;
case WSAEFAULT:
//AfxMessageBox("The lpSockAddrLen argument is incorrect.\n");
break;
case WSAEINVAL:
//AfxMessageBox("The socket is already bound to an address.\n");
break;
case WSAEISCONN:
//AfxMessageBox("The socket is already connected.\n");
break;
case WSAEMFILE:
//AfxMessageBox("No more file descriptors are available.\n");
break;
case WSAENETUNREACH:
//AfxMessageBox("The network cannot be reached from this host at this time.\n");
break;
case WSAENOBUFS:
//AfxMessageBox("No buffer space is available. The socket cannot be connected.\n");
break;
case WSAENOTCONN:
//AfxMessageBox("The socket is not connected.\n");
break;
case WSAENOTSOCK:
//AfxMessageBox("The descriptor is a file, not a socket.\n");
break;
case WSAETIMEDOUT:
//AfxMessageBox("The attempt to connect timed out without establishing a connection. \n");
break;
default:
TCHAR szError[256];
wsprintf(szError, "OnConnect error: %d", nErrorCode);
//AfxMessageBox(szError);
break;
}
if ( m_pSession )
m_pSession->OnClose();
return;
}
CAsyncSocket::OnConnect(nErrorCode);
m_iSent = m_iReceived = 0;
if ( nErrorCode == 0 ) {
m_bProcessing = FALSE;
m_bConnected = TRUE;
if ( _ProxyOnConnect() == PROXY_NONE )
if ( m_pSession )
m_pSession->OnConnect(nErrorCode);
}
// BOOL bTCPNoDelay = TRUE; // nSndBufLen = 16;
// SetSockOpt( SO_RCVBUF, &nRcvBufLen, sizeof(int) );
// SetSockOpt( TCP_NODELAY, &bTCPNoDelay, sizeof(BOOL), IPPROTO_TCP); //SOL_SOCKET
TRACE("OnConnect2\n");
}

void CDSocket::OnSend(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
int dwSent;
TSendBuf *ts;
TRACE("OnSend1 : SendHead=%x\n", m_pHead);
while ( m_pHead != NULL) {
ts = m_pHead;
TRACE( "First: ts->cbBuf:%d, ts->nSent: %d\n",ts->cbBuf, ts->nSent);
while ( ts->cbBuf != ts->nSent ) {
dwSent = CAsyncSocket::Send(ts->pBuf+ts->nSent, ts->cbBuf-ts->nSent);
if ( dwSent == SOCKET_ERROR ) {
if (GetLastError() != WSAEWOULDBLOCK) {
Close();
}
TRACE( "Send WSAEWOULDBLOCK",ts->cbBuf, ts->nSent);
goto EndOnSend;
}
TRACE("OnSend2: %d\n", dwSent);
m_iSent += dwSent;
TRACE("add:%d %d\n", ts->nSent, dwSent);
ts->nSent += dwSent;
TRACE( "ts->cbBuf:%d, ts->nSent: %d\n",ts->cbBuf, ts->nSent);
}
m_pHead = m_pHead->pNext;
if ( ts->pBuf )
delete [] ts->pBuf;
delete ts;
}
EndOnSend:
CAsyncSocket::OnSend(nErrorCode);
}

BOOL CDSocket::Add2Buf(const void* lpBuf, int nBufLen)
{
if ( m_prbf )
return m_prbf->Add(lpBuf, nBufLen);
else
return FALSE;
}

void CDSocket::OnReceive(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
TCHAR buff[8192];
TRACE("OnReceive0: %d\n", m_bProcessing);
if ( m_bProcessing )
return;

int nRead;
nRead = CAsyncSocket::Receive(buff, 8192);
TRACE("nRead: %d\n", nRead);

switch (nRead)
{
case 0:
Close();
break;
case SOCKET_ERROR:
if (GetLastError() != WSAEWOULDBLOCK) {
TRACE("Socket error\n");
Close();
}
break;
default:
{
if ( !m_prbf ) {
m_prbf = new CRecvBuf;
}
if ( !m_prbf ) {
Close();
}
else {
m_iReceived += nRead;
if ( !m_prbf->Add(buff, nRead) ) {
Close();
}
else {
// if ( nRead == 8192 ) // 可能还有,继续读取
// goto BeginRecv;
}
}
}
}
if ( m_ProxyType != PROXY_NONE && !m_bProxyPassed )
_ProxyOnReceive();
else
if ( m_pSession ) {
m_bProcessing = TRUE;
TRACE("OnReceive1\n");
m_pSession->OnReceive();
TRACE("OnReceive2\n");
m_bProcessing = FALSE;
}
TRACE("OnReceive3\n");

CAsyncSocket::OnReceive(nErrorCode);
}

void CDSocket::OnClose(int nErrorCode)
{
// TODO: Add your specialized code here and/or call the base class
TRACE("CDSocket::OnClose\n");
if ( m_prbf ) {
delete m_prbf;
m_prbf = NULL;
}

m_bConnected = FALSE;

CAsyncSocket::OnClose(nErrorCode);
if ( m_pSession )
m_pSession->OnClose();
}

BOOL CDSocket::IsConnected()
{
return m_bConnected;
}

int CDSocket::Send(const void* lpBuf, int nBufLen, int nFlags)
{
// TODO: Add your specialized code here and/or call the base class
BOOL bSendBufEmpty;

if ( m_pHead == NULL )
bSendBufEmpty = TRUE;
else
bSendBufEmpty = FALSE;

TRACE("Send1: %d\n, bSendBufEmpty: %d\n", nBufLen, bSendBufEmpty);
TSendBuf *ts = new TSendBuf;
if ( !ts ) {
Close();
return SOCKET_ERROR;
}

ts->pBuf = new char[nBufLen];
if ( !ts->pBuf ) {
delete ts;
Close();
return SOCKET_ERROR;
}
ts->cbBuf = nBufLen;
ts->nSent = 0;
ts->pNext = NULL;
memcpy(ts->pBuf, lpBuf, nBufLen);
if ( m_pHead == NULL ) {
m_pHead = m_pTail = ts;
}
else {
m_pTail->pNext = ts;
m_pTail = ts;
}

if ( bSendBufEmpty ) {
if ( !AsyncSelect( FD_READ | FD_WRITE | FD_OOB | FD_CLOSE ) ) {
int nErr = GetLastError();
switch ( nErr ) {
case WSANOTINITIALISED:
TRACE("AsyncSelect WSANOTINITIALISED: %d\n", nErr);
break;
case WSAENETDOWN:
TRACE("AsyncSelect WSAENETDOWN: %d\n", nErr);
break;
case WSAEINVAL:
TRACE("AsyncSelect WSAEINVAL: %d\n", nErr);
break;
case WSAEINPROGRESS:
TRACE("AsyncSelect WSAEINPROGRESS: %d\n", nErr);
break;
default:
TRACE("AsyncSelect default: %d\n", nErr);
break;
}
}
}

TRACE("Send2\n");

return nBufLen;
}


回复 点赞
Cowboy22 2003年11月14日
这是我们写的客户端代理连接代码(MFC- CAsyncSocket)

//.h

#if !defined(AFX_DSOCKET_H__D26AED20_3385_49D8_BB6F_CEFBCB6CEF34__INCLUDED_)
#define AFX_DSOCKET_H__D26AED20_3385_49D8_BB6F_CEFBCB6CEF34__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DSocket.h : header file
//

#include "proxy.h"
/////////////////////////////////////////////////////////////////////////////
// CDSocket command target
class CSession;

class CDSocket : public CAsyncSocket
{
// Attributes
protected:

struct TSendBuf {
int cbBuf;
int nSent;
char *pBuf;
TSendBuf *pNext;
};

struct TRecvBuf {
int cbBuf;
int nGot;
char *pBuf;
TRecvBuf *pNext;
};

class CRecvBuf { // 未同步,单线程
public:
BOOL Add(const void* lpBuf, int nBufLen)
{
if ( nBufLen <= 0 )
return FALSE;
TRecvBuf *tr = new TRecvBuf;
if ( !tr )
return FALSE;
tr->pBuf = new char [nBufLen];
if ( !tr->pBuf ) {
delete tr;
return FALSE;
}
tr->nGot = 0;
tr->cbBuf = nBufLen;
tr->pNext = NULL;
memcpy(tr->pBuf, lpBuf, nBufLen);
if ( m_pHead == NULL ) {
m_pHead = m_pTail = tr;
}
else {
m_pTail->pNext = tr;
m_pTail = tr;
}
m_nSize += nBufLen;
return TRUE;
}
int GetBufSize() { return m_nSize; }
int Receive(void* lpBuf, int nBufLen)
{
int rIdx = 0;
while ( m_pHead != NULL) {
TRecvBuf *tr = m_pHead;
if ( tr->cbBuf-tr->nGot <= (nBufLen-rIdx) ) {
m_pHead = m_pHead->pNext;
memcpy((char *)lpBuf+rIdx, tr->pBuf+tr->nGot, tr->cbBuf-tr->nGot);
rIdx += tr->cbBuf-tr->nGot;
if ( tr->pBuf )
delete [] tr->pBuf;
delete tr;
}
else {
memcpy((char *)lpBuf+rIdx, tr->pBuf+tr->nGot, nBufLen-rIdx);
tr->nGot += nBufLen-rIdx;
rIdx = nBufLen;
break;
}

if ( nBufLen == rIdx )
break;
}
m_nSize -= rIdx;
return rIdx;
}

public:
CRecvBuf()
{
m_nSize = 0;
m_pHead = m_pTail = NULL;
}
~CRecvBuf()
{
TRecvBuf *tr;
while (m_pHead != NULL)
{
tr = m_pHead;
m_pHead = m_pHead->pNext;
if ( tr->pBuf )
delete [] tr->pBuf;
delete tr;
}
}

protected:
TRecvBuf *m_pHead, *m_pTail;
int m_nSize;
};

public:

// Operations
public:
CDSocket(CSession *pSession);
virtual ~CDSocket();
BOOL Connect(LPCTSTR lpszHostAddress, UINT nHostPort);
void SetProxySetting(TProxyType ProxyType, CString strProxyIP, int nProxyPort,
BOOL bUserVerify=FALSE, char *ProxyUser=NULL, char *ProxyPwd=NULL);
BOOL IsConnected();

// Overrides
public:
int GetRecvBufSize();
BOOL Add2Buf(const void* lpBuf, int nBufLen);

__int64 GetTotalSent();
__int64 GetTotalReceived();
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CDSocket)
public:
virtual void OnConnect(int nErrorCode);
virtual void OnSend(int nErrorCode);
virtual void OnReceive(int nErrorCode);
virtual int Send(const void* lpBuf, int nBufLen, int nFlags = 0);
virtual int Receive(void* lpBuf, int nBufLen, int nFlags = 0);
virtual void Close();
virtual void OnClose(int nErrorCode);
//}}AFX_VIRTUAL

// Generated message map functions
//{{AFX_MSG(CDSocket)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG

// Implementation
protected:
void CleanLst();

protected: // processing proxy.
TProxyType _ProxyOnConnect();
void _HttpProxyOnConnect();
void _Socks4ProxyOnConnect();
void _Socks5ProxyOnConnect();

TProxyType _ProxyOnReceive();
void _HttpProxyOnReceive();
void _Socks4ProxyOnReceive();
void _Socks5ProxyOnReceive();

protected:
TSendBuf *m_pHead, *m_pTail;
// CPtrList m_lsSendBuf;
CRecvBuf *m_prbf;
CSession *m_pSession;
__int64 m_iSent, m_iReceived;

CString m_ServerIP;
int m_nServerPort;

TProxyType m_ProxyType;
BOOL m_bUserVerify, m_bProxyPassed;
int m_socks5step;
CString m_ProxyIP, m_ProxyUser, m_ProxyPwd;
int m_nProxyPort;
BOOL m_bConnected;


private:
BOOL m_bProcessing;
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_DSOCKET_H__D26AED20_3385_49D8_BB6F_CEFBCB6CEF34__INCLUDED_)
回复 点赞
anglely168 2003年11月14日
关于http代理,有个问题请教,客户端连接代理后,代理转发的是不是也是http数据包还是?要是,那是不是要在目标机器上写一个http服务器程序侦听http数据包(80端口)?怎么告诉代理数据转发到哪个目标机器上?我的msn:zuowenping@msn.com,请指教!
回复 点赞
zjlgigi 2003年11月13日
正想找这方面的资料,谢谢了~
回复 点赞
ablefirst 2003年11月13日
感谢!
学习
回复 点赞
xiaohyy 2003年11月13日
mark
回复 点赞
sevencat 2003年11月13日
{
PBYTE pInit;
int nHostLen;
DWORD hostIP;

if(nlu->settings.dnsThroughProxy)
{
if((hostIP=inet_addr(nloc->szHost))==INADDR_NONE)
nHostLen=lstrlen(nloc->szHost)+1;
else nHostLen=4;
}
else
{
if((hostIP=DnsLookup(nlu,nloc->szHost))==0)
return 0;
nHostLen=4;
}
pInit=(PBYTE)malloc(6+nHostLen);
pInit[0]=5; //SOCKS5
pInit[1]=1; //connect
pInit[2]=0; //reserved
if(hostIP==INADDR_NONE)
{ //DNS lookup through proxy
pInit[3]=3;
pInit[4]=nHostLen-1;
memcpy(pInit+5,nloc->szHost,nHostLen-1);
}
else
{
pInit[3]=1;
*(PDWORD)(pInit+4)=hostIP;
}
*(PWORD)(pInit+4+nHostLen)=htons(nloc->wPort);
if(NLSend(nlc,pInit,6+nHostLen,MSG_DUMPPROXY)==SOCKET_ERROR)
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLSend",GetLastError());
free(pInit);
return 0;
}
free(pInit);
}

if(!WaitUntilReadable(nlc->s,30000))
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"WaitUntilReadable",GetLastError());
return 0;
}

len=NLRecv(nlc,buf,sizeof(buf),MSG_DUMPPROXY);
if(len<7 || buf[0]!=5 || buf[1])
{
if(len!=SOCKET_ERROR)
{
if(len<7 || buf[0]!=5) SetLastError(ERROR_BAD_FORMAT);
else switch(buf[1])
{
case 1: SetLastError(ERROR_GEN_FAILURE); break;
case 2: SetLastError(ERROR_ACCESS_DENIED); break;
case 3: SetLastError(WSAENETUNREACH); break;
case 4: SetLastError(WSAEHOSTUNREACH); break;
case 5: SetLastError(WSAECONNREFUSED); break;
case 6: SetLastError(WSAETIMEDOUT); break;
case 7: SetLastError(ERROR_CALL_NOT_IMPLEMENTED); break;
case 8: SetLastError(ERROR_INVALID_ADDRESS); break;
default: SetLastError(ERROR_INVALID_DATA); break;
}
}
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLRecv",GetLastError());
return 0;
}
//connected
return 1;
}

static int NetlibInitHttpsConnection(struct NetlibConnection *nlc,struct NetlibUser *nlu,NETLIBOPENCONNECTION *nloc)
{ //rfc2817
NETLIBHTTPHEADER httpHeaders[3];
NETLIBHTTPREQUEST nlhrSend={0},*nlhrReply;
char szUrl[512];

memset(httpHeaders,0,sizeof(httpHeaders));

nlhrSend.cbSize=sizeof(nlhrSend);
nlhrSend.requestType=REQUEST_CONNECT;//后面会直接用CONNECT方法(一般的我们可能用GET,POST之类的方法,代理好像就是用的CONNECT方法)
nlhrSend.flags=NLHRF_DUMPPROXY|NLHRF_SMARTAUTHHEADER;
if(nlu->settings.dnsThroughProxy)
{
_snprintf(szUrl,sizeof(szUrl),"%s:%u",nloc->szHost,nloc->wPort);
if(inet_addr(nloc->szHost)==INADDR_NONE)
{
httpHeaders[0].szName="Host";
httpHeaders[0].szValue=szUrl;
nlhrSend.headersCount++;
}
}
else
{
struct in_addr addr;
DWORD ip=DnsLookup(nlu,nloc->szHost);
if(ip==0) return 0;
addr.S_un.S_addr=ip;
_snprintf(szUrl,sizeof(szUrl),"%s:%u",inet_ntoa(addr),nloc->wPort);
}
nlhrSend.szUrl=szUrl;
nlhrSend.headers=httpHeaders;
nlhrSend.headersCount=0;
if(NetlibHttpSendRequest((WPARAM)nlc,(LPARAM)&nlhrSend)==SOCKET_ERROR)
return 0;
nlhrReply=(NETLIBHTTPREQUEST*)NetlibHttpRecvHeaders((WPARAM)nlc,MSG_DUMPPROXY);
if(nlhrReply==NULL) return 0;
if(nlhrReply->resultCode<200 || nlhrReply->resultCode>=300)
{
NetlibHttpSetLastErrorUsingHttpResult(nlhrReply->resultCode);
Netlib_Logf(nlu,"%s %d: %s request failed (%u %s)",__FILE__,__LINE__,nlu->settings.proxyType==PROXYTYPE_HTTP?"HTTP":"HTTPS",nlhrReply->resultCode,nlhrReply->szResultDescr);
NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
return 0;
}
NetlibHttpFreeRequestStruct(0,(LPARAM)nlhrReply);
//connected
return 1;
}


struct NETLIBHTTPREQUEST_tag
{
int cbSize;
int requestType; //a REQUEST_
DWORD flags;
char *szUrl;
NETLIBHTTPHEADER *headers; //If this is a POST request and headers
//doesn't contain a Content-Length it'll be added automatically
int headersCount;
char *pData; //data to be sent in POST request.
int dataLength; //must be 0 for REQUEST_GET/REQUEST_CONNECT
int resultCode;
char *szResultDescr;
};

typedef struct
{
char *szName;
char *szValue;
} NETLIBHTTPHEADER;
虽然有些结构没有贴出来,但是具体的思路基本上就是这样了。
回复 点赞
sevencat 2003年11月13日
static int NetlibInitSocks4Connection(struct NetlibConnection *nlc,struct NetlibUser *nlu,NETLIBOPENCONNECTION *nloc)
{
PBYTE pInit;
int nUserLen,nHostLen,len;
BYTE reply[8];

nUserLen=lstrlen(nlu->settings.szProxyAuthUser);
nHostLen=lstrlen(nloc->szHost);
pInit=(PBYTE)malloc(10+nUserLen+nHostLen);
pInit[0]=4; //SOCKS4
pInit[1]=1; //connect
*(PWORD)(pInit+2)=htons(nloc->wPort);
if(nlu->settings.szProxyAuthUser==NULL) pInit[8]=0;
else lstrcpy(pInit+8,nlu->settings.szProxyAuthUser);
if(nlu->settings.dnsThroughProxy)
{
if((*(PDWORD)(pInit+4)=inet_addr(nloc->szHost))==INADDR_NONE)
{
*(PDWORD)(pInit+4)=0x01000000;
lstrcpy(pInit+9+nUserLen,nloc->szHost);
len=10+nUserLen+nHostLen;
}
else len=9+nUserLen;
}
else
{
*(PDWORD)(pInit+4)=DnsLookup(nlu,nloc->szHost);
if(*(PDWORD)(pInit+4)==0)
{
free(pInit);
return 0;
}
len=9+nUserLen;
}
if(NLSend(nlc,pInit,len,MSG_DUMPPROXY)==SOCKET_ERROR)
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLSend",GetLastError());
free(pInit);
return 0;
}
free(pInit);

if(!WaitUntilReadable(nlc->s,30000))
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"WaitUntilReadable",GetLastError());
return 0;
}

len=NLRecv(nlc,reply,sizeof(reply),MSG_DUMPPROXY);
if(len<sizeof(reply) || reply[1]!=90)
{
if(len!=SOCKET_ERROR)
{
if(len<sizeof(reply)) SetLastError(ERROR_BAD_FORMAT);
else switch(reply[1])
{
case 91: SetLastError(ERROR_ACCESS_DENIED); break;
case 92: SetLastError(ERROR_CONNECTION_UNAVAIL); break;
case 93: SetLastError(ERROR_INVALID_ACCESS); break;
default: SetLastError(ERROR_INVALID_DATA); break;
}
}
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLRecv",GetLastError());
return 0;
}
//connected
return 1;
}

static int NetlibInitSocks5Connection(struct NetlibConnection *nlc,struct NetlibUser *nlu,NETLIBOPENCONNECTION *nloc)
{ //rfc1928
int len;
BYTE buf[256];

buf[0]=5; //yep, socks5
buf[1]=1; //one auth method
buf[2]=nlu->settings.useProxyAuth?2:0;
if(NLSend(nlc,buf,3,MSG_DUMPPROXY)==SOCKET_ERROR)
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLSend",GetLastError());
return 0;
}

if(!WaitUntilReadable(nlc->s,10000))
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"WaitUntilReadable",GetLastError());
return 0;
}

len=NLRecv(nlc,buf,2,MSG_DUMPPROXY); //confirmation of auth method
if(len<2 || (buf[1]!=0 && buf[1]!=2))
{
if(len!=SOCKET_ERROR)
{
if(len<2) SetLastError(ERROR_BAD_FORMAT);
else SetLastError(ERROR_INVALID_ID_AUTHORITY);
}
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLRecv",GetLastError());
return 0;
}

if(buf[1]==2)
{ //rfc1929
int nUserLen,nPassLen;
PBYTE pAuthBuf;

nUserLen=lstrlen(nlu->settings.szProxyAuthUser);
nPassLen=lstrlen(nlu->settings.szProxyAuthPassword);
pAuthBuf=(PBYTE)malloc(3+nUserLen+nPassLen);
pAuthBuf[0]=1; //auth version
pAuthBuf[1]=nUserLen;
memcpy(pAuthBuf+2,nlu->settings.szProxyAuthUser,nUserLen);
pAuthBuf[2+nUserLen]=nPassLen;
memcpy(pAuthBuf+3+nUserLen,nlu->settings.szProxyAuthPassword,nPassLen);
if(NLSend(nlc,pAuthBuf,3+nUserLen+nPassLen,MSG_DUMPPROXY)==SOCKET_ERROR)
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLSend",GetLastError());
free(pAuthBuf);
return 0;
}
free(pAuthBuf);

if(!WaitUntilReadable(nlc->s,10000))
{
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"WaitUntilReadable",GetLastError());
return 0;
}

len=NLRecv(nlc,buf,sizeof(buf),MSG_DUMPPROXY);
if(len<2 || buf[1])
{
if(len!=SOCKET_ERROR)
{
if(len<2) SetLastError(ERROR_BAD_FORMAT);
else SetLastError(ERROR_ACCESS_DENIED);
}
Netlib_Logf(nlu,"%s %d: %s() failed (%u)",__FILE__,__LINE__,"NLRecv",GetLastError());
return 0;
}
}

回复 点赞
发动态
发帖子
网络编程
创建于2007-09-28

7878

社区成员

6.4w+

社区内容

VC/MFC 网络编程
社区公告
暂无公告