我打算实现一个小的torrent客户端。我从这里获取我的信息:http://wiki.theory.org/BitTorrent_Tracker_Protocol。
我想向tracker发送一个get请求来获取对等点列表。我是否应该设置udp连接并在端口80连接到udp://tracker.thepilatebay.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;
}这是我从torrent文件中得到的
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¶发布于 2012-12-04 13:40:40
你有没有检查gethostbyname是否返回了有效地址?我认为您不应该添加http://或udp://协议字符串部分作为gethostbyname参数。
struct hostent *hp = gethostbyname("tracker.thepiratebay.org");
if(!hp)
{
herror("gethostbyname(): ");
exit(1);
}添加此行以确保gethostbyname正常工作。
发布于 2013-11-11 07:26:18
该网站上给出的示例不适用于UDP通信。它用于通过TCP进行通信,更具体地说,是HTTP。
发布于 2017-05-13 06:38:02
如果跟踪器使用UDP,则不应发送GET请求,而应在指定端口建立连接,然后执行以下4个步骤:
通过读取16字节的响应来发送连接request
的对等体的数量
UDP连接总体上只需要较少的数据包来交换相同数量的信息,但它在实现客户端方面涉及更多:)
此wiki详细介绍了UDP消息应包含的内容。它们类似于您发送给对等体的消息(也就是说,它们使用编码成固定字节长度的big endian into )
或者specs可以提供帮助
https://stackoverflow.com/questions/13693203
复制相似问题