4

我想实现一个有点洪流的客户端。我从这里获取我的信息:http ://wiki.theory.org/BitTorrent_Tracker_Protocol 。

我想向跟踪器发送获取请求以获取对等列表。我应该建立一个 udp 连接并在 80 端口连接到 udp://tracker.thepiratebay.org 吗?这是我的请求消息的样子吗?

"udp://tracker.thepiratebay.org??info_hash=12345678901234567890
&peer_id=ABCDEFGHIJKLMNOPQRST
port=6888
&downloaded=0
&left=0
&event=started "

这是我的代码的一部分:

    char *requestToSend;
    int sock;
    struct sockaddr_in servAddr; 
    struct sockaddr_in fromAddr;    
    int fromSize; 
    int respStringLen;

    int portNum =80;
    char data_recv[ECHOMAX];

    char *hash="12345678901234567890";
    char *id="ABCDEFGHIJKLMNOPQRST";
    char *temp ="udp://tracker.thepiratebay.org??info_hash=12345678901234567890\n&peer_id=ABCDEFGHIJKLMNOPQRST\nport=6888\n&downloaded=0\n&left=0\n&event=started";
    requestToSend = malloc(sizeof(temp)+1);
    sprintf(requestToSend, "%s??info_hash=%s\n&peer_id=%s\nport=%s\n&downloaded=0\n&left=0\n&event=started\0","udp://tracker.thepiratebay.org", hash,id,"6888");
    printf("%s to send \n",  requestToSend);

   /* Create a datagram/UDP socket */
    if ((sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0){
        printf("fail create socket");
        return 0;
    }

    /* Construct the server address structure */
    struct hostent *hp = gethostbyname("udp://tracker.thepiratebay.org");   
    memset(&servAddr, 0, sizeof(servAddr));    /* Zero out structure */
    servAddr.sin_family = AF_INET;                 /* Internet addr family */
    memcpy( (char *) &servAddr.sin_addr.s_addr, hp->h_addr, hp->h_length );
    servAddr.sin_port   = htons(portNum);     /* Server port */


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

    /* Recv a response */
    fromSize = sizeof(fromAddr);
    if ((respStringLen = recvfrom(sock, data_recv, ECHOMAX, 0, 
         (struct sockaddr *) &fromAddr, &fromSize)) != strlen(requestToSend)){
        printf("fail to recv");
        return 0;
    }

这是我从种子文件中得到的

    dict {
    announce => str = http://tracker.thepiratebay.org/announce (len = 40)
    announce-list => list [
        list [
            str = http://tracker.thepiratebay.org/announce (len = 40)
        ]
        list [
            str = udp://tracker.thepiratebay.org:80/announce (len = 42)
        ]
        list [
            str = http://tracker.openbittorrent.com/announce (len = 42)
        ]
        list [
            str = udp://tracker.openbittorrent.com:80/announce (len = 44)
        ]
    ]
    creation date => int = 1174816388
    encoding => str = UTF-8 (len = 5)
    info => dict {
        filehash => str =
¸¥£öüËXþÐS®(äfn6 (len = 20)
        length => int = 2222949
        name => str = Audacity.zip (len = 12)
        name.utf-8 => str = Audacity.zip (len = 12)
        piece length => int = 32768
        pieces => str = (null) (len = 0)
    }
}
d8:announce40:http://tracker.thepiratebay.org/announce13:announce-listll40:http:                         //tracker.thepiratebay.org/announceel42:udp://tracker.thepiratebay.org:80/announ                         ceel42:http://tracker.openbittorrent.com/announceel44:udp://tracker.openbittorre                         nt.com:80/announceee13:creation datei1174816388e8:encoding5:UTF-84:infod8:fileha                         sh20:
¸¥£öüËXþÐS®(äfn66:lengthi2222949e4:name12:Audacity.zip10:name.utf-812:Audacity.z                         yf3-ûBÎNrl lengthi32768e6:pieces1360:þ]úÙÉÅ'NÕæ+gd3fi6è6¶
4

3 回答 3

1

该网站上给出的示例不适用于 UDP 通信。它用于通过 TCP 进行通信,更具体地说,是 HTTP。

于 2013-11-10T23:26:17.787 回答
1

你检查 gethostbyname 确实返回了一个有效的地址吗?我认为您不应该将 http:// 或 udp:// 协议字符串部分添加为 gethostbyname 参数。

struct hostent *hp = gethostbyname("tracker.thepiratebay.org");
if(!hp)
{
  herror("gethostbyname(): ");
  exit(1);
}

添加此行以确保 gethostbyname 确实可以正常工作。

于 2012-12-04T05:40:40.357 回答
0

如果 tracker 使用UDP,您不应该发送GET请求,而是在指定端口建立连接,然后执行 4 个步骤:

  1. 发送连接请求
  2. 通过读取 16 字节的响应来确认连接请求,并保持连接 ID
  3. 发送带有连接 ID 的通知
  4. 解析announce response,它的大小取决于指定的peer数量

全部的 UDP 连接需要更少的数据包来交换相同数量的信息,但它更多地涉及为客户端实现:)

这个wiki详细介绍了 UDP 消息应该包含的内容。它们类似于您发送给对等方的消息(也就是说,它们使用编码为固定字节长度的大端整数)

或者规格可以提供帮助

于 2017-05-12T22:38:02.187 回答