疯了!要怎么写才能连接上Socks4代理服务器?

chixiao 2009-09-23 02:41:09
我要搞一个Socks4客户连接功能。
事先参考了以下的参考资料:
http://blog.csdn.net/wangzhanlili/archive/2005/09/08/474847.aspx
http://www.cnpaf.net/forum/viewthread.php?tid=19043

然后我找了一个socks4代理服务器:121.22.20.202:1080 经过telnet验证,证明是可以连接的。

然后我写了一段代码,本意是通过这个代理连接上百度网站.

int Test3()
{

WSADATA wsd;

SOCKET sHost; // 代理服务器套接字

SOCKADDR_IN servAddr; // 代理服务器地址

char buf[BUF_SIZE]; // 接收数据缓冲区

int retVal; // 返回值

if (WSAStartup(MAKEWORD(2, 2), &wsd) != 0)
{

printf("WSAStatup failed!\n");
return 1;
}

// 创建套接字
sHost = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (INVALID_SOCKET == sHost)
{
printf("socket failed!\n");
WSACleanup();
return -1;
}

// 设置服务器地址
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr("121.22.20.202"); //socks4代理服务器的IP
servAddr.sin_port = htons(1080); // Socks4代理服务器的端口号
int nServAddlen = sizeof(servAddr);

// 连接代理服务器
retVal = connect(sHost, (LPSOCKADDR)&servAddr, sizeof(servAddr));
if (SOCKET_ERROR == retVal)
{
printf("Connect failed!\n");
closesocket(sHost);
WSACleanup();
return -1;
}


char buff[100] = {0};
memset(buff,0,100);
struct sock4req1 *m_proxyreq;
m_proxyreq = (struct sock4req1 *)buff;
m_proxyreq->VN = 4;
m_proxyreq->CD = 1;
m_proxyreq->Port = htons(80);     // 80端口
m_proxyreq->IPAddr = inet_addr("119.75.213.61"); // baidu的IP
strcpy(m_proxyreq->other , "");
retVal = ::send(sHost, buff, 9, 0);

struct sock4ans1 *m_proxyans;
m_proxyans = (struct sock4ans1 *)buff;
memset(buff,0,100);
retVal = ::recv(sHost, buff, 100, 0);

if(m_proxyans->VN != 0 || m_proxyans->CD != 90)
{
char * m_sError = "通过代理连接主站不成功!";
closesocket(sHost);

MessageBox(NULL, m_sError, "test", MB_OK);
return -1 ;
}
return 0;
}

结果是connect代理服务器没有出错,但发送连接请求,却没有得到回应,始终是"通过代理连接主站不成功!"

不知是哪个环节出了错,请各位兄弟帮忙指点!
...全文
5974 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
wenh7788 2009-09-23
  • 打赏
  • 举报
回复
职业帮顶
OboyingO 2009-09-23
  • 打赏
  • 举报
回复
顶了
贪玩的老鼠 2009-09-23
  • 打赏
  • 举报
回复
WSAStartup(MAKEWORD(2, 2), &wsd)你还是用SOCK2的版本协议.
是不是应该换掉
CoderOfVC 2009-09-23
  • 打赏
  • 举报
回复
嗯。。过程就跟你说的一样,recv到数据的时候就判断一下,有没有成功之类的,这个应答的数据看一下RFC文档就知道了。。
chixiao 2009-09-23
  • 打赏
  • 举报
回复
再次感谢阿蔡。
我知道Socks5是在socks4的基础上加了一个认证的步骤。

不过我对Winsock不是很熟。

我的大体过程是这样的:

先connect socks4代理服务,然后如果connect 这个函数没出错,则直接send一个socks4请求报文,再recv 一下socks4的应答报文。

不知道这样的处理过程是否有毛病?
CoderOfVC 2009-09-23
  • 打赏
  • 举报
回复
还有我上面的代码是建立在你已经与代理服务器连接好,并已经协商好的基础上的,上面的函数只是用来发送连接到目标主机的命令的。
CoderOfVC 2009-09-23
  • 打赏
  • 举报
回复
晕。。不一样也大同小异吧,socks5基本上只比socks4多了一个密码认证而已。。。改一下咯。。
chixiao 2009-09-23
  • 打赏
  • 举报
回复
谢谢阿蔡。您的代码是连接socks5代理的。
但是socks4的请求和回应的格式和socks5是不一样的。
CoderOfVC 2009-09-23
  • 打赏
  • 举报
回复
其中的...是我删掉的一些代码,你可以自己处理。。。
CoderOfVC 2009-09-23
  • 打赏
  • 举报
回复
没看你的代码,照你的意思就是连接服务器的时候不成功。给你一段代码你看有没有用吧。。。


//发送连接请求的命令,s已经连接到代理服务器的套接字,dwIP要连接到的目标IP地址,uPort要连接到的目标端口
int CSocks::SendConnectCommand(SOCKET s,DWORD dwIP,USHORT uPort)
{
/*+----+-----+-------+------+----------+----------+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1 |  1 | X'00' |  1 | Variable |   2  |
+----+-----+-------+------+----------+----------+ */

char szCommand[512];
int iSend; //发送了多少字节
int iRecv; //接收的字节数
memset(szCommand,0,512);

szCommand[0] = 0x05;
szCommand[1] = 0x01;
szCommand[3] = 0x01;

*((DWORD*)(szCommand + 4)) = dwIP; //IP
*((USHORT*)(szCommand + 8)) = uPort; //端口

iSend = send(s,szCommand,10,0);
if (SOCKET_ERROR == iSend)
{
.。。。
return -1;
}

memset(szCommand,0,512);
iRecv = recv(s,szCommand,512,0);
if (SOCKET_ERROR == iRecv)
{
。。。。
return -1;
}

if (0x05 != szCommand[0])
{
.。。。
return -1;
}

if (0x00 != szCommand[1])
{
shutdown(s,2);
closesocket(s);
CString strError;
switch(szCommand[1])
{
case 1:
strError = "general SOCKS server failure ";
break;
case 2:
strError = "connection not allowed by ruleset ";
break;
case 3:
strError = "Network unreachable ";
break;
case 4:
strError = "Host unreachable ";
break;
case 5:
strError = "Connection refused ";
break;
case 6:
strError = "TTL expired ";
break;
case 7:
strError = "Command not supported ";
break;
case 8:
strError = "Address type not supported ";
break;
case 9:
strError = " to X\'FF\' unassigned ";
break;
default:
strError = " Unknow error ";
break;
}
。。。。。
return -1;
}
return 0;
}

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧