ftp中的空闲断开

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wk_bjut_edu_cn/article/details/86505837

 为什么要空闲断开?

对于服务端而言,由于连接数和内存的限制,我们不可能对一个长时间处于不活跃的客户端,单独维护一个fd,一个进程/线程始终为其服务,fd单个进程上限默认值为1024,由于内存的限制,也不能无限制的分配出进程或者线程为其服务,这个时候我们就需要断开在规定时间内没有任何动作的客户端,腾出内存为其他客户端服务。

控制连接空闲断开实现

1.首先是安装信号SIGALRM并启动定时闹钟

unsigned int alarm(unsigned int seconds);

alarm()函数的主要功能是设置信号传送闹钟,即用来设置信号SIGALRM在经过参数seconds秒数后发送给目前的进程。如果未设置信号SIGALARM的处理函数,那么alarm()默认处理终止进程。

如果在seconds秒内再次调用了alarm函数设置了新的闹钟,则后面定时器的设置将覆盖前面的设置,即之前设置的秒数被新的闹钟时间取代。

由于闹钟是安装在while循环中,如果在未超时的时间内,又收到命令,那么就会重新设置闹钟,之前那个闹钟就会销毁。

//启动一个闹钟
void start_cmdio_alarm(void)
{
	if (tunable_idle_session_timeout > 0) {
		// 安装信号
		signal(SIGALRM, handle_alarm_timeout);
		// 启动闹钟
		alarm(tunable_idle_session_timeout);
	}
}

2.信号处理函数

在信号处理函数中关闭控制连接套接字

void handle_alarm_timeout(int sig)
{
	//关闭读的一半
	shutdown(p_sess->ctrl_fd, SHUT_RD);
	//给客户端应答
	ftp_reply(p_sess, FTP_IDLE_TIMEOUT, "Timeout.");
	//关闭写的这一半
	shutdown(p_sess->ctrl_fd, SHUT_WR);
	exit(EXIT_FAILURE);
}

如果在闹钟到来之前没有收到任何命令,则在SIGALRM信号处理程序中关闭控制连接,并给客户421 Timeout的响应,并且退出会话。

数据连接空闲断开实现

1.首先是安装信号SIGALRM并启动定时闹钟

注意:

如果当前处于数据传输的状态,那么即使控制连接通道空闲(在空闲时间没有收到任何客户端的命令)也不应该退出会话。实现方法,只需要将先前设定的闹钟关闭。

但是有这样一种情况,数据连接通道建立了,在一定时间没有传输数据,那么也应该将整个会话断开。所以数据连接中需要有自己的闹钟。

//重新安装SIGALRM信号,并启动闹钟
void start_data_alarm(void)
{
	if (tunable_data_connection_timeout > 0) {
		//安装信号
		signal(SIGALRM, handle_sigalrm);
		// 启动闹钟,取代了先前的那个闹钟
		alarm(tunable_data_connection_timeout);
	}
	//如果数据连接通道没有开启超时,应该将控制连接通道设置的闹钟关闭掉
	else if (tunable_idle_session_timeout > 0) {
		// 关闭先前安装的闹钟	
		alarm(0);
	}
}

2.信号处理函数

如果此时还处在数据传输的状态,比如上传或者下载文件中,那么应该重置数据传输标志,并指重新启动闹钟,也就是重新计算超时时间。如果当前不处于数据传输的状态,那么提示超时,然后退出连接。

那么如何判断是否正在处于数据传输之中呢?如果处于数据传输,肯定要进行是否限速的判断,所在在限速函数中将数据传输标志置为1。

//数据连接通道超时对应的函数
//重新安装信号的处理函数
void handle_sigalrm(int sig)
{
	//数据连接通道超时了,并且当前未处于数据传输的状态
	if (!p_sess->data_process) {
		ftp_reply(p_sess, FTP_DATA_TIMEOUT, "Data timeout. Reconnect. Sorry.");
		exit(EXIT_FAILURE);
	}

	//否则,当前处于数据传输的状态收到了超时信号
	p_sess->data_process = 0;
	//重新启动数据超时闹钟
	start_data_alarm();
}

 

猜你喜欢

转载自blog.csdn.net/wk_bjut_edu_cn/article/details/86505837