什么';这个SOCKS代理请求出了什么问题? 我目前尝试在我的C++程序中实现SOCKS 4/5功能(即,如果需要的话,可以通过给定的SOCKS代理重定向任意协议和主机)。我纯粹是为Windows开发,所以使用Winsock 2

什么';这个SOCKS代理请求出了什么问题? 我目前尝试在我的C++程序中实现SOCKS 4/5功能(即,如果需要的话,可以通过给定的SOCKS代理重定向任意协议和主机)。我纯粹是为Windows开发,所以使用Winsock 2,c++,winsock,socks,C++,Winsock,Socks,我的问题比简单的“这是如何工作的”稍微抽象一些。我已经阅读了SOCKS 4的RFC(我决定先实现SOCKS 4,因为它的请求中要处理的字节更少),但是我正在努力创建我需要发送的C字符串() 目前,我定义了一个名为Socks4Msg的结构,如下所示: struct Socks4Msg { const static uint8_t version = 0x04; //SOCKS version 4 (obviously) const static uint8_t command = 0x01; //

我的问题比简单的“这是如何工作的”稍微抽象一些。我已经阅读了SOCKS 4的RFC(我决定先实现SOCKS 4,因为它的请求中要处理的字节更少),但是我正在努力创建我需要发送的C字符串()

目前,我定义了一个名为Socks4Msg的结构,如下所示:

struct Socks4Msg {
const static uint8_t version = 0x04; //SOCKS version 4 (obviously)
const static uint8_t command = 0x01; //1 is TCP CONNECT command
const static uint8_t nullbyte = 0x00; //null byte sent at message end

uint16_t port; //16 bit/2 byte port (network order)
uint32_t ip; //32 bit/4 byte IP address (network order)
Socks4Msg(uint16_t p, uint32_t i) : port(p), ip(i) { }
};
创建实际套接字并执行工作的函数就在这里(其中p和h持有要通过代理进行测试的端口和主机——p是一个字符串,用于保持与我已经实现的HttpProxy的兼容性)。port和addr是类的一部分,分别是int和string;它们是代理服务器的详细信息

int Socks4Proxy::test(std::string p, std::string h) const {
uint16_t network_port = htons(str_to_numt<uint16_t>(p));
uint32_t network_ip = hostname_to_ip(h);
Socks4Msg msg_struct(network_port,network_ip);

SOCKET s = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
int last_error;
if(s == INVALID_SOCKET) {
              last_error = WSAGetLastError();
              std::cerr << "Failed to initialise socket! Error code: " << last_error << std::endl; 
              return 2;
}

sockaddr_in st_addr;
st_addr.sin_family = AF_INET;
st_addr.sin_port = htons(port);
ipaddr_t ip = inet_addr(addr.c_str());
st_addr.sin_addr.S_un.S_addr = ip;

if(connect(s,(sockaddr*)&st_addr,sizeof(st_addr))!=0) {
                                                      last_error = WSAGetLastError();
                                                      std::cerr << "Socket failed to connect. Error code: " << last_error << std::endl;
                                                      return 2;  
}

uint8_t message[13];
uint8_t* message_ptr;
memset(message, 0, 13);
message_ptr = message;
*message_ptr = msg_struct.version;
message_ptr++;
*message_ptr = msg_struct.command;
message_ptr++;
*message_ptr = msg_struct.port;
message_ptr += 2;
*message_ptr = msg_struct.ip;
message_ptr += 4;
*message_ptr = 'b'; message_ptr++; *message_ptr = 'o'; message_ptr++; *message_ptr = 'b'; message_ptr++;
*message_ptr = msg_struct.nullbyte;
message_ptr++;
*message_ptr = 0x00;
char smessage[13];
memcpy(smessage, message, 13);

int return_val;
while(return_val = send(s, smessage, strlen(smessage), 0)) {
                       if(return_val == SOCKET_ERROR) {
                                     last_error = WSAGetLastError();
                                     std::cerr << "Writing data failed. Error code: " << last_error << std::endl;
                                     return 2;
                       }
                       //implement return_val < strlen(message) here
                       else break;
}
//remainder of function
int Socks4Proxy::test(std::string p,std::string h)常量{
uint16网络端口=htons(str到numt(p));
uint32_t network_ip=hostname_to_ip(h);
Socks4Msg消息结构(网络端口、网络ip);
SOCKET s=套接字(AF_INET、SOCK_STREAM、IPPROTO_TCP);
int last_错误;
if(s==无效的_套接字){
最后一个错误=WSAGetLastError();

std::cerr首先
message\u ptr
uint8\u t*
并且
*message\u ptr=msg\u struct.ip;
是错误的。您应该将
message\u ptr
转换为
uint\u 32t*
,然后分配数据,如
*((uint32\u t*)message ptr)=msg_struct.ip;
否则,msg_struct.ip将转换为uint8\u t,然后进行赋值。其他字段也存在同样的问题

检查此项并让我知道它是否再次运行:)

顺便说一句,我认为Wireshark网络流量分析仪可以帮助您搜索此类问题

更新

可能更好的方法是创建一个表示要发送的消息的结构,并将
message_ptr
强制转换到此结构上的指针。但不要忘记告诉编译器不要添加任何填充

更新2

网络和主机字节顺序


不要忘记,您应该使用hton、ntoh、htonl或ntohl函数更改字节顺序。

首先
消息ptr
uint8*=msg_struct.ip;
否则,msg_struct.ip将转换为uint8\u t,然后进行赋值。其他字段也存在同样的问题

检查此项并让我知道它是否再次运行:)

顺便说一句,我认为Wireshark网络流量分析仪可以帮助您搜索此类问题

更新

可能更好的方法是创建一个表示要发送的消息的结构,并将
message_ptr
强制转换到此结构上的指针。但不要忘记告诉编译器不要添加任何填充

更新2

网络和主机字节顺序


不要忘了应该使用hton、ntoh、htonl或ntohl函数更改字节顺序。

谢谢你的建议。好的,我添加了cast*((uint16_t*)消息和*((uint32_t*)消息)分别用于端口和IP。但没有更改。Wireshark报告消息体为0x04 0x01,这非常好,因为它是正确的,只是被严重截断。非常均匀。:Pcheck strlen(smessage)值。它可能非常小,因为您的文本中可能有“\0”,协议消息不是文本;)据我所知,它将比您预期的至少少1个字节,因为将整个内容放入结构中的想法是
*message\u ptr=msg\u struct.nullbyte;
:这根本不是一个坏主意。但可能应该这样做几个小时前,我还留了一些头发,但至少还剩下一些。:)干杯,我来看看会发生什么。我看到你是新来的。只是一个小小的建议-不要忘记单击+并接受解决方案,以感谢其他ppl的帮助。祝你好运;)结果!strlen()返回2。这就是我的问题!坐在那里盯着每一行看了一会儿,我就再也没有想到。谢谢,我会的。谢谢你的建议。好的,我添加了演员表*((uint16_t*)message_ptr)和*((uint32_t*)message_ptr)分别用于端口和IP。但没有更改。Wireshark报告消息体为0x04 0x01,这非常好,因为它是正确的,只是被严重截断。非常均匀。:Pcheck strlen(smessage)值。它可能非常小,因为您的文本中可能有“\0”,协议消息不是文本;)据我所知,它将比您预期的至少少1个字节,因为将整个内容放入结构中的想法是
*message\u ptr=msg\u struct.nullbyte;
:这根本不是一个坏主意。但可能应该这样做几个小时前,我还留了一些头发,但至少还剩下一些。:)干杯,我来看看会发生什么。我看到你是新来的。只是一个小小的建议-不要忘记单击+并接受解决方案,以感谢其他ppl的帮助。祝你好运;)结果!strlen()返回2。这就是我的问题!坐在那里盯着每一行看了一会儿,我从来没有想到过。谢谢,我会的。