c++ - 用 C++ 连接到 UDP 跟踪器

标签 c++ udp bittorrent tracker

我正在尝试使用下面的代码连接到 UDP 跟踪器服务器,但我没有从跟踪器收到任何响应...

我从这个链接中收集了我能收集到的信息: http://xbtt.sourceforge.net/udp_tracker_protocol.html

我以为我明白了......但显然没有。代码执行良好,然后在调用 RecvFrom 时挂起。所以我猜我要么没有发送正确的数据,要么我将其发送到错误的地方......

struct ConnectionIdRequest_t {

    uint64_t connectionId;
    uint32_t action;
    int32_t transactionId;
} typedef ConnectionIdRequest;

const bool UdpTorrentTrackerComm::initiateConnection(const int amountUploaded, 
const int amountDownloaded, 
const int amountLeft) {

    struct sockaddr_in serverAddress, clientAddress;
    struct hostent * host;
    struct in_addr address;

    //Setup dummy client address
    clientAddress.sin_family = AF_INET;
    clientAddress.sin_addr.s_addr = htonl(INADDR_ANY);
    clientAddress.sin_port = htons(0);

    //Setup server address
    serverAddress.sin_family = AF_INET;
    serverAddress.sin_port = htons(portNumber);

    //SETUP in_addr server address
    //If we have an IP
    if (trackerAddress) {

        if (isIp4Address(*trackerAddress)) {

            //retrieve hostname from ip address 
            if (inet_aton(trackerAddress->c_str(), &address)) {

                host = gethostbyaddr((const char *) &address, sizeof(address), AF_INET);
                trackerHostname = new std::string(host->h_name);
            }
            else {
                return false;
            }
        }
        else {
            return false;
        }
    }
    else {
        //retrieve ip address from hostname
        host = gethostbyname(trackerHostname->c_str());
        address.s_addr = ((struct in_addr *) host->h_addr_list)->s_addr;
        trackerAddress = new std::string(inet_ntoa(address));
    }
std::cout << *trackerAddress << std::endl;
    //Convert trackerAddress to network format
    if(!inet_aton(trackerAddress->c_str(), &serverAddress.sin_addr)) {
        return false;
    }

    int sockFd = -1;
    //Add IPv6 in the future
    if ((sockFd = Socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        return false;
    }

    //Bind my address to the socket
    if (Bind(sockFd, (struct sockaddr *) &clientAddress, sizeof(clientAddress)) == - 1) {
        return false;
    }

    std::cout << "SendTo\n";
    ConnectionIdRequest * idRequest = createConnectionIdRequest();
    if (SendTo(sockFd, idRequest, sizeof(*idRequest), 0, 
        (struct sockaddr *) &serverAddress, sizeof(serverAddress)) == -1) {
        return false;
    }
    timeRequestSent = clock();
std::cout << "Sent: " << idRequest->connectionId << "|||" << idRequest->action << "|||" << idRequest->transactionId << std::endl;
    std::cout << "RecvFrom\n";
    char buffer[3000];
    socklen_t serverAddressLength = sizeof(serverAddress);
    while(true) {
        if (RecvFrom(sockFd, buffer, 3000, 0, 
            (struct sockaddr *) &serverAddress, &serverAddressLength) == - 1) {
            break;
            std::cout << "breaking...\n";
        }
    }
    std::cout << "The buffer is: " << buffer << std::endl;
    Close(sockFd);

    return true;
}

ConnectionIdRequest * UdpTorrentTrackerComm::createConnectionIdRequest() {

    ConnectionIdRequest * idRequest = new ConnectionIdRequest;
    generatePeerId();
    idRequest->connectionId = htonll(0x41727101980);
    idRequest->action = htonl(CONNECT);
    idRequest->transactionId = htonl(*peerId);

    return idRequest;
}

编辑:好吧,我做了 Arvid 建议的一项更改,但这没有任何帮助。我正在检查并确保我正在将所有发送的字节转换为网络字节顺序......也许我错过了一些东西......

最佳答案

看起来您正在混淆交易 ID 和对等 ID。他们是不同的。事务 ID 是您发送的 cookie,用于将返回的数据包与正确的请求进行匹配。

您似乎还没有初始化connectionID。您必须在初始连接消息中将其设置为神奇的 64 位数字。 0x41727101980

您可以找到替代协议(protocol)描述here .

关于c++ - 用 C++ 连接到 UDP 跟踪器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19122150/

相关文章:

c++ - 使用XMVECTOR时内存访问异常

c++ - Arduino 与 Visual C++ 串口通信

c++ - LLDB 为局部变量给出 "use of undeclared identifier"错误

python - 在 Python 中使用 Rasterbar libtorrent 进行樱桃选择

c++ - 库文件结构的常见做法

javascript - WebRTC 数据通道服务器到客户端的 UDP 通信

c++ - 在同一端口上绑定(bind)两个多播套接字

php - 在 PHP 中创建简单的客户端/服务器 UDP 示例

node.js - NodeJs如何写入文件

metadata - 从 torrent 集合中的单个文件生成 torrent/magnet 链接