功能超时未按预期工作

时间:2018-07-16 12:21:45

标签: c++ raspberry-pi

我才刚刚开始学习C ++,我想测试一下我在Raspberry上学到的东西。目前,我的项目包括通过WiFi将数据从Raspberry传输到另一个。这工作得很好,但是当Raspberry客户端从WiFi断开连接时就会出现问题。此时,服务器将无限期等待。因此,为了避免这种情况,我在Google上搜索了“超时”功能,它是这样的:

class Timeout;
static Timeout * global_timeout_instance = 0;

class Timeout {
        public:
                int m_timeout;
                jmp_buf env;

                Timeout(int timeout) : m_timeout(timeout) {
                        if (global_timeout_instance) {
                                throw "Timeout already in use";
                        }
                        global_timeout_instance = this;
                }

                ~Timeout() {
                        stop();
                        global_timeout_instance = 0;
                }

                static void alarm_handler(int signum) {
                        longjmp(global_timeout_instance->env, 1);
                }

                void start() {
                        Timeout * ptr = this;
                        if (setjmp(env) != 0) {
                                // Don't do anything except throw here, since the state
                                // is... funky...
                                printf("Alarm fired: %p\n", ptr);
                                throw global_timeout_instance;
                        }
                        signal(SIGALRM, alarm_handler);
                        alarm(2);
                }


                void stop() {
                        alarm(0);
                }
};

因此,此功能非常有效,因为当连接断开时,程序将直接停止。但是我想在失去连接后采取一些措施。这是我的整个代码:

#include <exception>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <cstdio>
#include <setjmp.h>
#include <signal.h>

class Timeout;
static Timeout * global_timeout_instance = 0;

class Timeout {
        public:
                int m_timeout;
                jmp_buf env;

                Timeout(int timeout) : m_timeout(timeout) {
                        if (global_timeout_instance) {
                                throw "Timeout already in use";
                        }
                        global_timeout_instance = this;
                }

                ~Timeout() {
                        stop();
                        global_timeout_instance = 0;
                }

                static void alarm_handler(int signum) {
                        longjmp(global_timeout_instance->env, 1);
                }

                void start() {
                        Timeout * ptr = this;
                        if (setjmp(env) != 0) {
                                // Don't do anything except throw here, since the state
                                // is... funky...
                                printf("Alarm fired: %p\n", ptr);
                                throw global_timeout_instance;
                        }
                        signal(SIGALRM, alarm_handler);
                        alarm(2);
                }


                void stop() {
                        alarm(0);
                }
};

int main(int argc , char *argv[])
{
        int socket_desc , client_sock , c , read_size;
        struct sockaddr_in server , client;
        char client_message[2000];

        //Create socket
        socket_desc = socket(AF_INET , SOCK_STREAM , 0);
        if (socket_desc == -1)
        {
                printf("Could not create socket");
        }
        puts("Socket created");

        //Prepare the sockaddr_in structure
        server.sin_family = AF_INET;
        server.sin_addr.s_addr = INADDR_ANY;
        server.sin_port = htons( 8888 );

        //Bind
        if( bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0)
        {
                //print the error message
                perror("bind failed. Error");
                return 1;
        }
        puts("bind done");

        //Listen
        listen(socket_desc , 3);

        //Accept and incoming connection
        puts("Waiting for incoming connections...");
        c = sizeof(struct sockaddr_in);

        //accept connection from an incoming client
        client_sock = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c);
        if (client_sock < 0)
        {
                perror("accept failed");
                return 1;
        }
        puts("Connection accepted");

        //Receive a message from client
        while(1)
        {
                try
                {
                        Timeout timeout(1);
                        timeout.start();
                        read_size = recv(client_sock , client_message , 2000 , MSG_WAITALL);
                }
                catch(Timeout * t)
                {
                        printf("Timeout detected\n");
                        // Do some action later
                }
                printf("%d\n", read_size);
                if(client_message !="")
                {
                        puts(client_message);
                }
                else
                {
                        printf("Not Ok");
                }
                memset(client_message, 0, sizeof(client_message));
        }

        if(read_size == 0)
        {
                puts("Client disconnected");
                fflush(stdout);
        }
        else if(read_size == -1)
        {
                perror("recv failed");
        }


        return 0;
}

我不知道超时后该如何做一些动作。 这是程序停止时收到的消息:

  

触发了警报:在抛出一个实例后,调用了0x7eff8c40终止   “超时*”已终止

有人可以帮助我解决这个问题吗?

谢谢。

凯文

0 个答案:

没有答案