网络上找到的socket5 udp c++ 代码 可供参考

// ProxySocketSocksV5.h : header file
//

/*
使用Socks5代理协议的socket类,目前只支持UDP协议。

cxiaobao@163.com 24/09/2002
*/
#if !defined(AFX_PROXYSOCKETSOCKSV5_H__07BD21EA_0867_4F91_A82A_72F3AF706228__INCLUDED_)
#define AFX_PROXYSOCKETSOCKSV5_H__07BD21EA_0867_4F91_A82A_72F3AF706228__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

//验证方法选择 请求
struct SOCKS5SELECTREQEST
{
BYTE ver; //版本号,必须是5
BYTE nmethods; //认证方法的数量
BYTE methods[255]; //认证方法
/*
· '00' 不需要认证
· '01'    GSSAPI
· '02'    用户名/密码
· '03' -- X'7F'   由IANA分配
· '80' -- X'FE'  为私人方法所保留的
· 'FF'      没有可以接受的方法
*/
};

//验证方法选择 回应
struct SOCKS5SELECTANSWER
{
BYTE ver; //版本号,必须是5
BYTE method; //验证方法,是SOCKS5REQUEST1中methods[255]中的一个值
//具体见SOCKS5REQUEST1.methods[255]的说明
};

//验证 请求
struct SOCKS5AUTHENTICATE
{
BYTE ver; //版本号,为1
BYTE ulen; //用户名长度
BYTE user[255]; //用户名
BYTE plen; //密码长度
BYTE pass[255]; //密码
};

//验证 回应
struct SOCKS5AUTHANSWER
{
BYTE ver; //版本号
BYTE state; //验证状态
};

//Socks5命令 请求
struct SOCKS5COMMANDREQUEST
{
BYTE ver; //版本号
BYTE cmd; //命令
/*
CONNECT:'01'
BIND:'02'
UDP ASSOCIATE:'03'
*/
BYTE rsv; //保留,必须为0
BYTE type; //表明其后的地址类型
/*
· IPV4:X'01'
· 域名:X'03'
· IPV6:X'04'
*/
ULONG addr; //目标地址,这里只支持ipv4
/*取决于type
'01': 基于IPV4的IP地址,4个字节长
'03': 基于域名的地址,地址字段中的第一字节是以字节为单位的该域名的长度,没有结尾的NUL字节。
'04': 基于IPV6的IP地址,16个字节长
*/
WORD port; //目标端口(网络字节顺序)
};

//SOCKS5命令 回应
struct SOCK5COMMANDANSWER
{
BYTE ver; //版本号
BYTE rep; //回应消息
/*
· X'00'  成功
· X'01'  普通的SOCKS服务器请求失败
· X'02'  现有的规则不允许的连接
· X'03'  网络不可达
· X'04'  主机不可达
· X'05' 连接被拒
· X'06'  TTL超时
· X'07'  不支持的命令
· X'08'  不支持的地址类型
· X'09' - X'FF'  未定义
*/
BYTE rsv; //保留
BYTE type; //同SOCKS5COMMANDREQUEST
ULONG addr; //返回的地址
WORD port; //返回的端口(网络字节顺序)
};

//socks5规定的udp数据包头
struct SOCKS5UDPHEADER
{
WORD rsv; //保留
BYTE frag; //分段标志,如果不分段则为0
BYTE type; //同SOCKS5COMMANDREQUEST
ULONG addr; //目标地址,同SOCKS5COMMANDREQUEST
WORD port; //目标端口,同SOCKS5COMMANDREQUEST
};
/
// CProxySocketSocksV5 command target

class CChildView;
class CProxySocketSocksV5 : public CAsyncSocket
{
SOCKET m_SocketCommand; //与Sock5服务器交互的socket
BOOL m_bConnected;
ULONG m_AddrBinding;
WORD m_PortBinding;
// Attributes
public:
CChildView* m_pView;
char m_User[255]; //用户名
char m_Pass[255]; //密码
char m_Server[20]; //socks5 server ip
WORD m_Port;
// Operations
public:
CProxySocketSocksV5();
virtual ~CProxySocketSocksV5();

int SendTo(const void* lpBuf, int nBufLen,
UINT nHostPort, LPCTSTR lpszHostAddress = NULL, int nFlags = 0);
int SendTo(const void* lpBuf, int nBufLen,
const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags = 0);
int ReceiveFrom(void* lpBuf, int nBufLen,
CString& rSocketAddress, UINT& rSocketPort, int nFlags = 0);
int ReceiveFrom(void* lpBuf, int nBufLen,
SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags = 0);
// Overrides
public:
void Close();
UINT ConnectToProxyServer(const char* server = NULL,WORD nPort = 0, char* user = NULL, char* pass = NULL);
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CProxySocketSocksV5)
public:
virtual void OnReceive(int nErrorCode);
//}}AFX_VIRTUAL

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

// Implementation
protected:
};

/

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

#endif // !defined(AFX_PROXYSOCKETSOCKSV5_H__07BD21EA_0867_4F91_A82A_72F3AF706228__INCLUDED_)


/
// CProxySocketSocksV5

CProxySocketSocksV5::CProxySocketSocksV5()
{
m_Port = 0;
ZeroMemory(m_User,255);
ZeroMemory(m_Pass,255);
ZeroMemory(m_Server,20);
m_bConnected = FALSE;
m_AddrBinding = 0;
m_PortBinding = 0;
}

CProxySocketSocksV5::~CProxySocketSocksV5()
{
}


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

/
// CProxySocketSocksV5 member functions

//连接到socks5代理服务器,在发送或接收前先调用次函数
//函数返回0表示成功,返回其他数值表示失败,具体意义见代码
UINT CProxySocketSocksV5::ConnectToProxyServer(const char* server,WORD nPort, char* user, char* pass)
{
if(server != NULL)
strcpy(m_Server,server);
if(nPort != 0)
m_Port = nPort;
if( user != NULL)
strcpy (m_User,user);
if(pass != NULL)
strcpy (m_Pass,pass);

char buf[1024];
ASSERT(m_hSocket != INVALID_SOCKET);

if(m_SocketCommand != INVALID_SOCKET)
closesocket(m_SocketCommand);

m_SocketCommand = socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addr;
addr.sin_addr.s_addr = inet_addr(m_Server);
addr.sin_family = AF_INET;
addr.sin_port = htons(m_Port);

if(m_SocketCommand == INVALID_SOCKET)
return 1; //Create Socket Error
if(SOCKET_ERROR == connect(m_SocketCommand,(sockaddr*)&addr,sizeof(addr)))
{
closesocket (m_SocketCommand);
return 2; //connect socks server error;
}

SOCKS5SELECTREQEST selectrequest;
ZeroMemory(&selectrequest,sizeof(selectrequest));
selectrequest.ver = 5;
selectrequest.nmethods = 2;
selectrequest.methods[0] = 0;
selectrequest.methods[1] = 2;

if(SOCKET_ERROR  == send(m_SocketCommand,(char*)&selectrequest,4,0))
{
closesocket (m_SocketCommand);
return 3; //send error
}

ZeroMemory(buf,1024);
if(SOCKET_ERROR == recv(m_SocketCommand,buf,1024,0))
{
closesocket (m_SocketCommand);
return 4; //recv error
}

SOCKS5SELECTANSWER *pselectanswer = (SOCKS5SELECTANSWER *)buf;
if((pselectanswer->method != 0 && pselectanswer->method != 2) || pselectanswer->ver != 5)
{
closesocket (m_SocketCommand);
return 5; //无合适的验证方法
}

if(pselectanswer->method == 2)
{
SOCKS5AUTHENTICATE auth;
ZeroMemory(&auth,sizeof(auth));
auth.ver = 1;
auth.ulen = strlen(m_User)>254?254:strlen(m_User);
auth.plen = strlen(m_Pass)>254?254:strlen(m_Pass);
strncpy((char*)auth.user,m_User,auth.ulen);
strncpy((char*)auth.pass,m_Pass,auth.plen);
if(SOCKET_ERROR == send(m_SocketCommand,(char*)&auth,sizeof(auth),0))
{
closesocket (m_SocketCommand);
return 3; //send error
}
ZeroMemory(buf,1024);
if(SOCKET_ERROR == recv(m_SocketCommand,buf,1024,0))
{
closesocket (m_SocketCommand);
return 4;
}
SOCKS5AUTHANSWER *pAuthAnswer = (SOCKS5AUTHANSWER*)buf;
if(pAuthAnswer->state != 0)
{
closesocket (m_SocketCommand);
return 6; //验证错误
}
}

//connect to proxy server
SOCKS5COMMANDREQUEST commandrequest;
ZeroMemory(&commandrequest,sizeof(commandrequest));
commandrequest.addr = 0; //允许所有地址
int l= sizeof(addr);
GetSockName ((SOCKADDR*)&addr,&l);
commandrequest.port = addr.sin_port;
commandrequest.cmd = 3; //绑定udp端口
commandrequest.rsv = 0;
commandrequest.type = 1; //ipv4
commandrequest.ver = 5;

if(SOCKET_ERROR == send(m_SocketCommand,(char*)&commandrequest,sizeof(commandrequest),0))
{
closesocket (m_SocketCommand);
return 3; //send error
}
ZeroMemory(buf,1024);
if(SOCKET_ERROR == recv(m_SocketCommand,buf,1024,0))
{
closesocket (m_SocketCommand);
return 4;
}
SOCK5COMMANDANSWER* pCommandAnswer = (SOCK5COMMANDANSWER*)buf;
if(pCommandAnswer->rep != 0)
{
closesocket (m_SocketCommand);
return 7; //answer error;
}

m_PortBinding = pCommandAnswer->port;
m_AddrBinding = pCommandAnswer->addr;
in_addr inaddr;
inaddr.s_addr = m_AddrBinding;
TRACE("%s:%d\n",inet_ntoa(inaddr),ntohs(m_PortBinding));
m_bConnected = TRUE;

return 0;
}

int CProxySocketSocksV5::SendTo(const void* lpBuf, int nBufLen,UINT nHostPort, LPCTSTR lpszHostAddress, int nFlags)
{
SOCKADDR_IN addr_in;
addr_in.sin_family = AF_INET;
addr_in.sin_addr.s_addr = inet_addr(lpszHostAddress);
addr_in.sin_port = htons(nHostPort);
return SendTo (lpBuf,nBufLen,(SOCKADDR*)&addr_in,sizeof(addr_in),nFlags);
}
int CProxySocketSocksV5::SendTo(const void* lpBuf, int nBufLen,const SOCKADDR* lpSockAddr, int nSockAddrLen, int nFlags)
{
SOCKADDR_IN *paddr_in = (SOCKADDR_IN*)lpSockAddr,addr_in;
addr_in.sin_family = AF_INET;
addr_in.sin_addr.s_addr = m_AddrBinding;
addr_in.sin_port = m_PortBinding;

SOCKS5UDPHEADER udpHdr;
udpHdr.addr = paddr_in->sin_addr.s_addr;
udpHdr.frag = 0;
udpHdr.port = paddr_in->sin_port;
udpHdr.rsv = 0;
udpHdr.type = 1;

char *p = (char*)malloc(sizeof(udpHdr) + nBufLen);
memcpy(p,(char*)&udpHdr,sizeof(udpHdr));
memcpy(p + sizeof(udpHdr),lpBuf,nBufLen);
int rlt = CAsyncSocket::SendTo (p,sizeof(udpHdr) + nBufLen,(SOCKADDR*)&addr_in,sizeof(addr_in),0);
free(p);

return rlt;
}

void CProxySocketSocksV5::Close()
{
if(m_SocketCommand != INVALID_SOCKET)
closesocket(m_SocketCommand);
m_bConnected = FALSE;
CAsyncSocket::Close ();
}

int CProxySocketSocksV5::ReceiveFrom(void* lpBuf, int nBufLen,CString& rSocketAddress, UINT& rSocketPort, int nFlags)
{
int nSize = sizeof(SOCKS5UDPHEADER);
char *p = new char[nSize + nBufLen];
int rlt = CAsyncSocket::ReceiveFrom (p,nSize + nBufLen,rSocketAddress,rSocketPort,nFlags);
if(SOCKET_ERROR == rlt)
{
delete[] p;
return SOCKET_ERROR;
}
SOCKS5UDPHEADER* pUdpHdr = (SOCKS5UDPHEADER*)p;
in_addr inaddr;
inaddr.s_addr = pUdpHdr->addr;
rSocketAddress = inet_ntoa(inaddr);
rSocketPort = ntohs(pUdpHdr->port);
memcpy(lpBuf,p + nSize,rlt - nSize);

delete[] p;
return rlt - nSize;
}
int CProxySocketSocksV5::ReceiveFrom(void* lpBuf, int nBufLen,SOCKADDR* lpSockAddr, int* lpSockAddrLen, int nFlags)
{
char *p = new char[sizeof(SOCKS5UDPHEADER) + nBufLen];

int rlt = CAsyncSocket::ReceiveFrom (p,sizeof(SOCKS5UDPHEADER) + nBufLen,lpSockAddr,lpSockAddrLen,nFlags);
if(SOCKET_ERROR == rlt)
{
delete[] p;
return SOCKET_ERROR;
}
SOCKADDR_IN *paddr_in = (SOCKADDR_IN*)lpSockAddr;
SOCKS5UDPHEADER* pUdpHdr = (SOCKS5UDPHEADER*)p;
paddr_in->sin_addr.s_addr = pUdpHdr->addr;
paddr_in->sin_port = pUdpHdr->port;
memcpy(lpBuf,p + sizeof(SOCKS5UDPHEADER),nBufLen);
delete[] p;

return rlt;
}



void CProxySocketSocksV5::OnReceive(int nErrorCode) 
{
m_pView->OnReceive(nErrorCode);
CAsyncSocket::OnReceive(nErrorCode);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值