Bittorrent-клиент в C ++, время ожидания подключения к одноранговому неблокирующему сокету всегда истекает

РЕДАКТИРОВАТЬ::

Поэтому ответ, который я принял ниже, на самом деле не был проблемой. Я проверил через wireshark, что одноранговые узлы действительно передают по TCP для загрузки через торрент. Так что я должен быть в состоянии подключиться, но все попытки тайм-аут …


Поэтому я делаю битторрент-клиент на C ++ и использую библиотеку сокетов BSD для всех сетевых коммуникаций. У меня есть код для подключения к пирам по TCP, но время каждой попытки истекает. Я на 100% уверен, что одноранговые узлы действительны для файла, который я хочу загрузить, я начал загружать файл в Transmission, и к нему подключались те же одноранговые узлы.

Вот мой код подключения, первая часть просто добавляет группу пиров к вектору, чтобы я мог перебрать его и попробовать каждый пир:

(ПРИМЕЧАНИЕ: «Все системные вызовы в верхнем регистре являются просто функциями-обертками для обработки ошибок. Там нет никакого забавного дела.)

    char * HOST;
uint16_t PORT;

std::vector<char *> all_ips;
std::vector<uint16_t> all_ports;

all_ips.push_back("213.112.225.102");
all_ports.push_back(18715);

uint32_t i = 0;
for (; i < all_ips.size(); i++) {

HOST = all_ips[i];
PORT = all_ports[i];

struct sockaddr * saddr;
struct sockaddr_in addr;
struct addrinfo hints, * ai,  * it;
char strportnum[25];

memset(&hints, '\0', sizeof(hints));
hints.ai_flags = AI_ADDRCONFIG;
hints.ai_socktype = SOCK_STREAM;

snprintf(strportnum, 10, "%d", PORT);GetAddrInfo(HOST, strportnum, &hints, &ai);

for (it = ai; it != NULL; it = it->ai_next) {

if ((sockFd = Socket(AF_INET, SOCK_STREAM, 0)) != -1) {

saddr = ai->ai_addr;
saddr->sa_family = AF_INET;int res;
long arg;
fd_set myset;
struct timeval tv;
int valopt;
socklen_t lon;

// Set non-blocking
if( (arg = fcntl(sockFd, F_GETFL, NULL)) < 0) {
fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno));
exit(0);
}
arg |= O_NONBLOCK;
if( fcntl(sockFd, F_SETFL, arg) < 0) {
fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno));
exit(0);
}

// Trying to connect with timeout
res = Connect(sockFd, saddr, sizeof(*saddr));
if (res < 0) {

if (errno == EINPROGRESS) {

fprintf(stderr, "EINPROGRESS in connect() - selecting\n");

do {

//Set timeouts
tv.tv_sec = 20;
tv.tv_usec = 0;

FD_ZERO(&myset);
FD_SET(sockFd, &myset);

res = Select(sockFd + 1, NULL, &myset, NULL, &tv);

if (res < 0 && errno != EINTR) {
fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));

break;
}
else if (res > 0) {

// Socket selected for write
lon = sizeof(int);
if (getsockopt(sockFd, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) {
fprintf(stderr, "Error in getsockopt() %d - %s\n", errno, strerror(errno));break;
}

// Check the value returned...
if (valopt) {
fprintf(stderr, "Error in delayed connection() %d - %s\n", valopt, strerror(valopt));break;
}

break;
}
else {
fprintf(stderr, "Timeout in select() - Cancelling!\n");

break;
}
} while (1);
}
else {
fprintf(stderr, "Error connecting %d - %s\n", errno, strerror(errno));

break;
}
}
// Set to blocking mode again...
if( (arg = fcntl(sockFd, F_GETFL, NULL)) < 0) {
fprintf(stderr, "Error fcntl(..., F_GETFL) (%s)\n", strerror(errno));

break;
}

arg &= (~O_NONBLOCK);

if(fcntl(sockFd, F_SETFL, arg) < 0) {
fprintf(stderr, "Error fcntl(..., F_SETFL) (%s)\n", strerror(errno));

break;
}
}
}
freeaddrinfo(ai);
}

Я использовал этот сайт как руководство по неблокирующим сокетам:
http://developerweb.net/viewtopic.php?id=3196

3

Решение

Я настоятельно полагаю, что порт, к которому ваша программа пытается подключиться с помощью TCP, говорит по UDP. Последний стал общей базой торрент-связи.

Для справки, пожалуйста, смотрите эти две ссылки:

1

Другие решения

Других решений пока нет …

А ты уже прошел курс программирования? Супер скидка!
Прокачать скилл $$$
×