我才刚刚开始学习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终止 “超时*”已终止
有人可以帮助我解决这个问题吗?
谢谢。
凯文