C ++中的Bittorrent客户端,连接到非阻塞套接字上的对等总是超时

时间:2013-11-19 19:58:05

标签: c++ c sockets tcp bittorrent

EDIT ::

所以下面我接受的答案实际上不是问题。我通过wireshark验证了对等体确实通过TCP传输以进行种子下载。所以我应该可以连接,但所有尝试都会超时...


所以我在C ++中创建了一个bittorrent客户端,我正在使用BSD套接字库进行所有网络通信。我有一些代码通过TCP连接到对等,但每次尝试都超时。我100%确定对等体对我要下载的文件有效,我开始在传输中下载文件,并且正在连接相同的对等体。

这是我的连接代码,第一部分是简单地将一堆对等体添加到一个向量中,这样我就可以迭代它并尝试每个对等体:

(注意“所有大写系统调用只是用于错误处理目的的包装函数。那里没有任何有趣的业务发生。)

    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

1 个答案:

答案 0 :(得分:1)

我强烈认为您的程序尝试使用TCP连接的端口是UDP。后者成为洪流通信的共同基础。

供参考,请参阅以下两个链接: