【问题标题】:how to connect to a bit torrent tracker in c如何在c中连接到bit torrent tracker
【发布时间】:2012-12-04 03:58:47
【问题描述】:

我想连接到一个比特流跟踪器http://tracker.thepiratebay.org。 gethostbyname() 一直返回 null,我应该如何解决这个问题?你还发现这段代码有什么问题吗?

    int sock;
    struct sockaddr_in servAddr; 
    int portNum = 80;

    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
          printf("fail create socket");
          return 0;
    }

    char *path = "http://tracker.thepiratebay.org/";
    struct hostent *hp = gethostbyname(path);   
    if(hp==NULL){
        printf("null");
    else{

        memset(&servAddr, 0, sizeof(servAddr));   
        servAddr.sin_family = AF_INET;                 
        memcpy( (char *) &servAddr.sin_addr.s_addr, (char *)  hp->h_addr, hp->h_length );
        servAddr.sin_port   = htons(portNum);    
    }

    //send request to tracker server 
    if (send(sock, requestToSend, strlen(requestToSend), 0) != strlen(requestToSend)){
        printf("fail send");
        return 0;
    }

【问题讨论】:

  • TPB 的追踪器不是永久关闭了吗?

标签: c tcp udp bittorrent tracker


【解决方案1】:

这里的问题是 http://tracker.thepiratebay.org/ 是一个 URL,但 gethostbyname() 只需要主机名。主机名是tracker.thepiratebay.org

如果您只使用libcurl 会更容易,它将为您处理所有 HTTP 内容。在连接到 HTTP 服务器的应用程序中使用 libcurl 是非常常见的;这是一个很棒的图书馆。它肯定比套接字编程更容易。

使用getaddrinfo()

gethostbyname() 的现代替代品是getaddrinfo()。并不是gethostbyname() 没有做你想做的事,而是getaddrinfo() 在所有可以想象的方面都更好。

struct addrinfo hint, *ap;
memset(&hint, 0, sizeof(hint));
hint.ai_family = AF_UNSPEC;
hint.ai_socktype = SOCK_STREAM;
int r = getaddrinfo("tracker.thepiratebay.org", "http", &hint, &ap);

这不仅会为您提供所需主机的地址,还会填写端口号。你可以使用"http"作为端口,也可以使用"80"作为端口,它们是一样的(只要/etc/services有正确的入口)。

其他问题

这一行是错误的。

memcpy( (char *) &servAddr.sin_addr.s_addr, (char *)  hp->h_addr, hp->h_length );

你不知道gethostbyname()返回了一个IPv4地址,尝试将它复制到struct sockaddr_in中是愚蠢的。如果gethostbyname() 返回了一个 IPv6 地址,那么您刚刚破坏了您的堆栈,您的程序将会崩溃——或者更糟糕的是,它可能不会崩溃。

要么检查它是否返回 IPv4 地址,要么简单地将 hp-&gt;h_addr 复制到从 malloc(hp-&gt;h_length) 返回的通用 struct sockaddr 中。这有点难看,但就是这样。

最后,将参数转换为memcpy() 是错误的。这不是错误,但它是错误的。不要这样做,否则可能会导致合法的编译器错误被抑制,例如,如果您不小心将 int 转换为 char *

【讨论】:

  • 感谢迪特里希·埃普的回复。我不能使用任何库。你知道我可以使用哪个函数将 url 存储到 &servAddr.sin_addr.s_addr 中。
  • @help: 你不能使用任何库?真的吗?你确定吗?这听起来真的很奇怪。很多人说他们不能使用库,但我不知道为什么,我很想知道原因。
  • 用于学校项目,“必须在不使用任何其他第三方库的情况下实现整个协议。”
  • @help 你可以让getaddrinfo() 帮你处理
  • @user9000:啊!我完全错过了这是gethostbyname() 而不是getaddrinfo()。不错的收获。我会编辑答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多