Итак, я пишу простой Bittorrent-клиент. Для соединения с UDP Tracker я написал следующий код. Это не работает
void Tracker::connectUDP(int port, int transaction_id) {
// create a Datagram socket
sockaddr_in server_address;
int sock_fd = socket(AF_INET, SOCK_DGRAM, 0);
if(sock_fd < 0)
return;
// set timeout
timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;
setsockopt(sock_fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
bzero(&server_address, sizeof(server_address));
server_address.sin_family = AF_INET;
server_address.sin_addr.s_addr = inet_addr((this -> url).c_str());
server_address.sin_port = htons(port);
char requestBuffer[16] = { 0 };
generateConnectionBuffer(requestBuffer, transaction_id);
char responseBuffer[16] = { 0 };
socklen_t serverAddressLength = sizeof(server_address);
sendto(sock_fd, requestBuffer, sizeof(requestBuffer), 0, (struct sockaddr *) &server_address, sizeof(server_address));
std::cout << "REQUEST SENT" << std::endl;
recvfrom(sock_fd, responseBuffer, sizeof(responseBuffer), 0, (struct sockaddr *) &server_address, &serverAddressLength);
std::cout << responseBuffer << std::endl;
}
void generateConnectionBuffer(char *buffer, uint32_t transaction_id) {
uint64_t connectionID = htobe64(connectionID);
uint32_t action = htonl(CONNECT);
uint32_t tID = htonl(transaction_id);
memcpy(buffer + 0, &connectionID, 8);
memcpy(buffer + 8, &action, 4);
memcpy(buffer + 12, &tID, 8);
}
Я попытался использовать структуру для requestBuffer вместо символьного буфера. Не сработало. Попытка использовать различные способы преобразования в сетевые байты, включая мои собственные письменные функции, не сработала.
Проблема в том, что если я не установлю тайм-аут, время соединения истекает. Я знаю, что это потому, что передан неправильный буфер, и когда истекает время ожидания, я получаю пустой буфер (также ожидается). Так что я думаю, что буфер неправильно установлен. Поправь меня, если я ошибаюсь.
Буду признателен за любую помощь. Thankks