网络断开并重新启动后如何重新连接到TCP服务器?

时间:2019-08-02 09:43:20

标签: c linux sockets tcp

我有一个树莓派pi连接到TCP服务器并每隔几秒钟发送一些数据,我希望能够处理所有类型的故障和断开连接,所以目前我正在尝试测试断开连接我正在连接的华为USB加密狗。

我有一个线程在后台运行,并定期检查连接。当我移除USB加密狗并在稍后将其重新插入时,代码不会重新连接,我需要有关如何使其更坚固的帮助。目前,在服务器端,我看到插入USB加密狗后,我看到客户端已连接,但立即断开了连接。

该线程称为KeepSocketOpen,在这里我调用8.8.8.8的ping函数以查看连接是否仍处于活动状态,这是我的代码,我是套接字编程的新手,所以请原谅: >

int ping(char *ipaddr)
{
    char *command = NULL;
    FILE *fp;
    int x, match=0;
    char* result = NULL;
    size_t len = 0;

    asprintf (&command, "%s %s -p 50 -r 3", "fping", ipaddr);
    //printf ("%s %s -q 2>&1", "fping", ipaddr);
    fp = popen(command, "r");
    if (fp == NULL) {
        fprintf(stderr, "Failed to execute fping command\n");
        free(command);
        return -1;
    }

    while(getline(&result, &len, fp) != -1) {
        fputs(result, stdout);
        //printf("%s",result);
    }


    for(x=0;x<len;x++)
    {
        if(x>5 && result[x]=='e'&& result[x-1]=='v'&&  result[x-2]=='i'&& result[x-3]=='l'&& result[x-4]=='a')
        {
            match=1;
            break;
        }
    }

    if(match==0)
        sleep(5);

    free(result);
    fflush(fp);
    if (pclose(fp) != 0) {
        perror("Cannot close stream.\n");
    }
    free(command);
    //printf("%s\r\n",result);

    if(match==0)
        return -1;
    else 
        return 1;
}

void* KeepSocketOpen(void *arg)
{
    pthread_t id= pthread_self();
    char tcprxbuff[1024];
    int numbytes, status=0,attempts,reuse=1;
    struct timeval timeout={0};

    timeout.tv_sec=10;
    timeout.tv_usec=0;

    printf("in sock thread\r\n");

    while(1)
    {
        if(is_socket_connected==0)
        {
            sock=socket(AF_INET,SOCK_STREAM,0);
            addr.sin_family = AF_INET;
            addr.sin_port = htons(34879);
            addr.sin_addr.s_addr=inet_addr("X.X.X.X");
            attempts=0;
            setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&timeout,sizeof(timeout));
            setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&timeout,sizeof(timeout));
            setsockopt(sock, SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse));

            status=connect(sock, (struct sockaddr *) &addr,sizeof (addr));

            // wait for 5s and see if the socket has connected
            do
            {
                delay(5);
            }
            while(errno && attempts++<1000);

            if (attempts >=1000 || errno) // this is the fail case
            {
                printf("socket not connected %s\r\n",strerror(errno));
                is_socket_connected=0;
                close(sock);
                //shutdown(sock,SHUT_RDWR);
                sleep(30);
            }
            else
            {
                // fcntl(sock, F_SETFL, O_NONBLOCK);
                printf("socket reconnected %d,%s\r\n",attempts,strerror(errno));
                is_socket_connected=1;
                write(sock, "HI FROM RASPI", strlen("HI FROM RASPI"));
            }       
        }
        else
        {
            numbytes=read(sock,tcprxbuff,sizeof(tcprxbuff));
            if(numbytes==0)// if this is zero, socket was closed by server
            {
                is_socket_connected=0;
                while(close(sock)==-1);
            }
            else
            {
                printf("socket connected:%d\r\n",numbytes);
                status = ping("8.8.8.8");
                if (status!=-1) {
                    printf("socket still connected:%d\r\n",status);
                    is_socket_connected=1;
                } else {
                    printf("socket disconnected:%d\r\n",status);
                    is_socket_connected=0;
                    //shutdown(sock,SHUT_RDWR);

                    while(close(sock)==-1);

                }
            }
            sleep(30);
        }
    }
}

0 个答案:

没有答案
相关问题