C SOCKS5 代理接口未从代理服务器接收任何内容。
Posted
技术标签:
【中文标题】C SOCKS5 代理接口未从代理服务器接收任何内容。【英文标题】:C SOCKS5 proxy interface not receiving anything from proxy server. 【发布时间】:2014-11-20 02:54:47 【问题描述】:我制作了一个简单的 SOCKS5 代理 RFC 1928 实现,使用 C 套接字与在 localhost:9050 上运行的我的 Tor 守护程序进行通信。它可以编译并且工作正常,但是由于它没有 recv() 任何东西,所以它被阻塞了。
代码如下:
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
int main(int argc, char** argv)
struct addrinfo hints, *res;
int sockfd;
memset(&hints,0,sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("localhost","9050",&hints,&res);
sockfd = socket(res->ai_family,res->ai_socktype,res->ai_protocol);
int connected = connect(sockfd,res->ai_addr,res->ai_addrlen);
if (connected == -1)
perror("Error");
char buffer[256];
char msginit[256];
msginit[0] = '\5'; //Protocol number
msginit[1] = '\2'; //# of authentication methods
msginit[2] = '\0'; //no authentication
msginit[3] = '\2'; //user+pass auth
//get dest
memset(&hints,0,sizeof hints);
memset(res,0,sizeof *res);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
getaddrinfo("duckduckgo.com","80",&hints,&res);
struct sockaddr_in *ip = (struct sockaddr_in *)res->ai_addr;
uint32_t* addr=&(ip->sin_addr.s_addr);
//copy dest to request
memcpy (msginit+4,addr,sizeof (uint32_t));
send(sockfd, (void *)msginit, (size_t)strlen(msginit),0);
printf("Sent.\n");
recv(sockfd,buffer,256,0); //This is where it gets stuck!
printf("%s\n",buffer);
【问题讨论】:
它没有被卡住......你只是收到了 1 次,因为你调用了一次 recv。将 recv 函数放在一个循环中,它会打印你发送的消息多次。 我只尝试接收一次。它甚至没有这样做。 strace 显示它在调用 recv() 时卡住了。 【参考方案1】:我在下面的回答是错误的。更深入地研究它,有一个握手过程,还有更多需要发生的事情。我会在接下来的几天内回复我的想法。 (这也是我正在为自己做的事情)
就您的代码而言,您只会从响应中提取前 256 个字节。
有几个选项,具体取决于您需要多快的数据。最后,您可能不会看到太多差异(如果有的话)。但你确实有选择。
1 - 发出 立即 的 recv 调用开始一个循环,该循环一直运行,直到您获得整个响应。如果您尽快需要数据,我建议您使用此方法。确保在那里有一个 sleep/usleep 调用,否则你会很难在 CPU 上旋转。
它可能看起来像这样:
send(sockfd, (void *)msginit, (size_t)strlen(msginit),0);
printf("Sent.\n");
while (len_recv = recv(sockfd,buffer,256,0))
if (len_recv > 0)
// there was an error. handle it here.
// copy your buffer if you need to, otherwise...
printf("%s",buffer);
usleep(10000);
2 - 使用 MSG_WAITALL 选项,它将阻塞接收调用,直到它从请求的服务器接收到整个消息,然后从套接字中提取所有数据。这就是我每天处理数百万个套接字请求的方式。
len_recv = recv(sockfd,buffer,256,MSG_WAITALL);
if (len_recv > 0)
// start a while loop like above
// copy the buffer if you need to, or...
printf("%s",buffer);
就我个人而言,在我的代码运行速度非常快(每天数亿个请求)中,我使用了 MSG_WAITALL 选项和足够大的缓冲区来满足我的需要,这样我就不会循环我的 recv 调用。这可能对您不起作用,但好处是您不必在循环中考虑额外的 cpu 周期。如果您正在执行大量请求或需要解析数据而不仅仅是转储输出,这将特别方便。
如果您能提供更多关于您如何使用它的详细信息,我可以整理出更完整和经过测试的代码示例,并提供更直接的建议。
【讨论】:
以上是关于C SOCKS5 代理接口未从代理服务器接收任何内容。的主要内容,如果未能解决你的问题,请参考以下文章