Question

EDIT::

So the answer I accepted below was not actually the issue. I verified through wireshark that the peers are indeed transmitting over TCP for torrent downloads. So I should be able to connect, but all attempts timeout...


So I'm making a bittorrent client in C++ and I'm using the BSD sockets library for all network communications. I have some code to connect to peers over TCP but every attempt times out. I am 100% certain the peers are valid for the file I'm seeking to download, I started downloading the file in Transmission and the same peers were being connected to.

Here is my connect code, the first part is simply adding a bunch of peers to a vector so I can iterate over it and try each peer:

(NOTE" all of the upper-case system calls are just wrapper functions for error handling purposes. There isn't any funny business happening there.)

    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);
    }

I've been using this site as a guide to non-blocking sockets: http://developerweb.net/viewtopic.php?id=3196

Was it helpful?

Solution

I strongly assume the port your program is trying to connect to using TCP is speaking UDP. The latter became the common base of the torrent communication.

For reference please see those two links:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top