【发布时间】:2018-02-27 04:12:22
【问题描述】:
我正在编写一个与 SOCKS 5 客户端(maxthon 浏览器)通信的 SOCKS 5 服务器。我让它在没有身份验证的情况下工作。但是,当我添加身份验证时,
客户端向服务器发送用户/密码 服务器验证用户/通行证
服务器向客户端发送响应
+----+--------+
|VER | STATUS |
+----+--------+
| 1 | 1 |
+----+--------+
VER = 0x01 STATUS = 0x00(成功)
- 我可以假设这是身份验证的结束吗?
之后我尝试从客户端读取数据,
+----+-----+-------+------+----------+----------+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
但是此时读取的字节不等于该结构的大小所期望的字节。读取的字节数 == 0。
- 有什么问题?
如果我取消身份验证,我的服务器就可以正常工作。但是我想让它与它一起工作。
编辑
这是服务器验证客户端后的代码:
socks5_login SOCKS5_Login;
if (Str::Compare(UserName, PUCHAR("test")) == 0 && Str::Compare(Password, PUCHAR("test")) == 0) {
SOCKS5_Login.Version = 0x01;
SOCKS5_Login.Status = 0x00;
if (Http::SendProxyData(Settings->Sock, PCHAR(&SOCKS5_Login), sizeof(socks5_login), Settings->Func) != TRUE)
return FALSE;
UCHAR Status;
Settings->Func.Recv(Settings->Sock, PCHAR(Status), sizeof(UCHAR), 0);
if (Status != NO_ERROR)
return FALSE;
/*
The SOCKS request is formed as follows:
+----+-----+-------+------+----------+----------+
|VER | CMD | RSV | ATYP | DST.ADDR | DST.PORT |
+----+-----+-------+------+----------+----------+
| 1 | 1 | X'00' | 1 | Variable | 2 |
+----+-----+-------+------+----------+----------+
*/
socks5_request Request;
if (Http::ReadProxyData(Settings->Sock, PCHAR(&Request.SOCKS5_Header), sizeof(socks5_header), Settings->Func) != TRUE)
return FALSE;
if (Request.SOCKS5_Header.Command != 1/*CONNECT*/ &&
Request.SOCKS5_Header.AddressType != 1 /*IPv4*/ &&
Request.SOCKS5_Header.Version != 5 /*SOCKS Version 5*/)
return FALSE;
// ...
读取Request.SOCKS5_Header时,Http::ReadProxyData()函数返回FALSE(recv()返回0)。
【问题讨论】:
-
这就是 RFC1929 的工作原理,是的。您确定客户对您的回复满意吗?
-
@tadman 如果是这样的话,为什么在向客户端发送身份验证响应后我无法接收到结构?
-
您可能没有正确发送响应,而客户端正在等待某些事情发生,然后才说出其他内容。你确定数据已经从套接字中“刷新”了吗?
-
你说的“脸红”是什么意思?
-
"读取的字节数 == 0" - 如果
recv()返回 0,则表示对端正常断开连接。这可能意味着您没有正确发回您的响应,因此客户端最终失败并关闭连接。请显示您的实际代码,您可能做错了什么。