TCP connect() 错误代码 113(无路由器到主机) - Linux C++

TCP connect() 错误代码 113(无路由器到主机) - Linux C++

出现 Errno 代码 113(没有到主机的路由器)时如何排除故障?

我有一台Linux嵌入式设备,wifi模块处于并发模式。目前遇到一个问题,就是嵌入式设备在连接A设备时,通过“arp”命令获取A设备的IP,设置addrinfo结构(非阻塞),通过这个addrinfo进行Connect()函数,完成TCP握手。此时有几率会不断出现Errno code 113(no router to host)而导致连接失败。设备A和嵌入式设备确认没有防火墙设置。这个问题是间歇性的,错误出现5分钟以上后又恢复,过一段时间又出现。

附上相关代码

struct addrinfo hints, *servinfo, *p;
int rv;
char ipstr[INET6_ADDRSTRLEN];
bool SucessFlag = true;
static int failedtoconcnt[10];
static int StartRTC[10];
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;//ipv4 & ipv6
hints.ai_socktype = SOCK_STREAM;//tcp
cout << "Try to Connect IP: " << chIP << "Port "<< chPort << endl;
if (strlen(chIP) < 6)   return 2;

for(int j=0;j<2;j++){
    if ((rv = getaddrinfo(chIP, chPort, &hints, &servinfo)) != 0) {
        fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
        return -1;
    }
    void *addr;
    if (servinfo->ai_family == AF_INET) { // IPv4
      struct sockaddr_in *ipv4 = (struct sockaddr_in *)servinfo->ai_addr;
      addr = &(ipv4->sin_addr);
      inet_ntop(servinfo->ai_family, addr, ipstr, sizeof(ipstr));
    } else { // IPv6
      struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)servinfo->ai_addr;
      addr = &(ipv6->sin6_addr);
      inet_ntop(servinfo->ai_family, addr, ipstr, sizeof ipstr);
    }

    for (p = servinfo; p != NULL; p = p->ai_next) {
    if ((sockfd[id] = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) {
        perror("client: socket Error");
        continue;
    }

    if (sockfd[id] != 0){
        for(int i=0;i<MaxID;i++){
            if (ModTcpIPA->InvConnectID[i] == 1){
                if (sockfd[id] == sockfd[i+1] && id != i+1){
                    DC_DEBUG_NL("sockfd[%d]=%d", id, sockfd[id]);
                    DC_DEBUG_NL("sockfd[%d]=%d", i+1, sockfd[i+1]);
                    CloseAllSock();
                    SucessFlag = false;
                }
            }
        }
    }

    fcntl(sockfd[id], F_SETFL, O_NONBLOCK);
    if (connect(sockfd[id], p->ai_addr, p->ai_addrlen) == 0)  break;
    sleep(1);
    printf("1errno: %2d\t%s\n",errno,strerror(errno));
    if (connect(sockfd[id], p->ai_addr, p->ai_addrlen) == 0)  break;
    sleep(1);
    printf("2errno: %2d\t%s\n",errno,strerror(errno));
    if (connect(sockfd[id], p->ai_addr, p->ai_addrlen) == 0)  break;
    sleep(1);
    printf("3errno: %2d\t%s\n",errno,strerror(errno));
    if (connect(sockfd[id], p->ai_addr, p->ai_addrlen) == 0)  break;
    sleep(1);
    printf("4errno: %2d\t%s\n",errno,strerror(errno));
}
if (p == NULL) {
    DC_DEBUG_NL("client: failed to connect");
    fprintf(stderr, "client: failed to connect\n");
    close(sockfd[id]);
    return 1;
}
inet_ntop(p->ai_family, toget_in_addr((struct sockaddr *)p->ai_addr), ipstr, sizeof ipstr);
freeaddrinfo(servinfo);
    if (SucessFlag == true){
        break;
    }
}
return 0;

答案1

输入以下内容你会看到什么:

$ route

在您想要运行该软件的机器上的控制台中?

您应该看到类似以下内容的内容:

Kernel IP routing table
Destination     Gateway    Genmask   Flags Metric Ref    Use Iface
default         1.2.3.4    0.0.0.0   UG    0      0        0 eth0

目的地default(0.0.0.0) 是使路由工作的关键。有点像魔术。如果没有其他 IP 匹配,则使用默认 IP 发送数据,然后网关负责进一步转发或处理数据包。

如果你的路线都UG没有标志列,那么您完全没有输入网关。如果有这样一行,那么可能是网关 IP 出了问题。

如果您有名称解析问题,请尝试-n命令行选项:

$ route -n

如果这不是问题所在,我会通过打印出代码来确保我获取了正确的 IP 地址。这样你就能知道代码中是否有错误。我看不出有什么问题,尽管你的代码很难读(它是老旧的 C 而不是 C++...你的类在哪里?我有一个项目要做这样的事情这里它使用另一个项目处理 IP 地址,因为太乱了!)

相关内容