tcp服务器accept的作用,TCP_DEFER_ACCEPT

1. 设置TCP_DEFER_ACCEPT

int val = 10; // time_out

if (setsockopt(sock_descriptor, IPPROTO_TCP, TCP_DEFER_ACCEPT, &val, sizeof(val))== -1)

{perror("setsockopt");

exit(1);}

2. TCP_DEFER_ACCEPT的效果 正常的tcp三次握手过程:

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手

设置TCP_DEFER_ACCEPT后

第一次握手:建立连接时,客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;

第二次握手:服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;

第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,连接并不进入ESTABLISHED状态,而是在第一个真正有数据的包到达后才进入ESTABLISHED,完成连接的建立。TCP_DEFER_ACCEPT的超时在第三次握手时候,如果客户段迟迟不发送数据,服务器 连接将一直处于syn_recv状态。此时内核会重传 syn_ack ,重传的次数可以通过 sysctl -w net.ipv4.tcp_synack_retries=3来设置,如果3次重传后,客户端依然没有数据,在等待 设置TCP_DEFER_ACCEPT时候指定的超时时间后(这个时间单位为s,可是测试看来并不精准的执行),系统将回收连接,并不对客户端发出rst或者fin包。

内核中源码如下:

第三次握手会调用函数tcp_v4_hnd_req:

static struct sock *tcp_v4_hnd_req(struct sock*sk, struct sk_buff*skb)

{

......

struct request_sock *req = inet_csk_search_req(sk,&prev, th->source,

iph->saddr, iph->daddr);//查找半连接队列,返回req

if (req)

return tcp_check_req(sk, skb, req, prev);//ack的处理

......

}

我们看函数tcp_check_req

struct sock *tcp_check_req(struct sock*sk,struct sk_buff*skb,

struct request_sock *req,

struct request_sock **prev)

{

......

/*If TCP_DEFER_ACCEPT is set, drop bare ACK.*/

if (inet_csk(sk)->icsk_accept_queue.rskq_defer_accept&&

TCP_SKB_CB(skb)->end_seq== tcp_rsk(req)->rcv_isn+ 1) {//如果选项设置了,并且是裸

ack,丢弃该ack;选项值得默

认为1

inet_rsk(req)->acked= 1;

return NULL;

}

child = inet_csk(sk)->icsk_af_ops->syn_recv_sock(sk, skb,

req, NULL);//如果非裸ack或没设置选项则建立连接(req从半连接

队列到连接队列及tcp状态变为ESTABLISHED)

......

}

我们在用户层写socket程序时,可以通过setsockopt来设置TCP_DEFER_ACCEPT选项:

val = 5;

setsockopt(srv_socket->fd, SOL_TCP, TCP_DEFER_ACCEPT,&val, sizeof(val));

里面 val 的单位是秒,注意如果打开这个功能,kernel 在 val 秒之内还没有收到数据,不会继续唤醒进程,而是直接丢弃连接。

在内核空间会调用:

static int do_tcp_setsockopt(struct sock*sk, int level,

int optname, char __user*optval, int optlen)

{

struct tcp_sock *tp = tcp_sk(sk);

struct inet_connection_sock *icsk = inet_csk(sk);

int val;

......     if (get_user(val, (int __user *)optval))//拷贝用户空间数据

return -EFAULT;

......

case TCP_DEFER_ACCEPT:

icsk->icsk_accept_queue.rskq_defer_accept= 0;

if (val> 0) {//如果setsockopt中设置val为0,则不开始TCP_DEFER_ACCEPT选项

/* Translate valuein seconds to number of

* retransmits */

while (icsk->icsk_accept_queue.rskq_defer_accept

val > ((TCP_TIMEOUT_INIT / HZ) <<

icsk->icsk_accept_queue.rskq_defer_accept))//根据设置的val决定重传次数,譬

如val=10,重传次数为3;后面我们可以看到,只有

/proc/sys/net/ipv4/tcp_synack_retries的

值小于等于通过val算出的重传次数时,这个val才

起作用

icsk->icsk_accept_queue.rskq_defer_accept++;

icsk->icsk_accept_queue.rskq_defer_accept++;

}

break;

......

}

内核是通过函数inet_csk_reqsk_queue_prune进行重传synack:

void inet_csk_reqsk_queue_prune(struct sock*parent,

const unsigned long interval,

const unsigned long timeout,

const unsigned long max_rto)

{

struct inet_connection_sock *icsk = inet_csk(parent);

struct request_sock_queue *queue = &icsk->icsk_accept_queue;

struct listen_sock *lopt = queue->listen_opt;

int max_retries = icsk->icsk_syn_retries? : sysctl_tcp_synack_retries;//默认synack

重传次数为5

int thresh = max_retries;

unsigned long now = jiffies;

struct request_sock **reqp,*req;

int i, budget;

......

if (queue->rskq_defer_accept)

max_retries = queue->rskq_defer_accept;//设定支持选项时候的重传次数

budget = 2 * (lopt->nr_table_entries/ (timeout / interval));

i = lopt->clock_hand;

do {

reqp=&lopt->syn_table[i];

while ((req =*reqp) != NULL){

if (time_after_eq(now, req->expires)){

if ((req->retrans

(inet_rsk(req)->acked&& req->retrans

&&!req->rsk_ops->rtx_syn_ack(parent, req, NULL)){//如果重传次数小于设定

的重传次数,就重传synack;这里可以看出两个并列的判断条件:req->retrans < thres

h和(inet_rsk(req)->acked && req->retrans < max_retries),第一个是当前req

的重传次数小于设定的最大重传次数,这里是5;第二个则是TCP_DEFER_ACCEPT;inet_rs

k(req)->acked则是在函数tcp_check_req中设定的,上面讨论过了,而max_retries则

为通过val计算的值,默认为1。这个重传次数决定了synack包的重传次数及最长超时时间,

显然两者中较大者起到决定性的作用。譬如,默认重传为2,通过val计算出的max_retries

值为3,则将发送3次重传的synack及超时时间为12秒后,关闭连接

unsigned long timeo;

if (req->retrans++== 0)

lopt->qlen_young--;

timeo = min((timeout<retrans), max_rto);

req->expires= now + timeo;//每重传一次,超时值就按初始值

timeout(TCP_TIMEOUT_INIT)比值为2的等比

数列增加,如3 6 12 24 48 96

reqp = &req->dl_next;

continue;//继续循环

}

/* Drop this request*/

如果超时,如超过例子中的96秒,就将req从半连接队列里删除,丢弃连接

inet_csk_reqsk_queue_unlink(parent, req, reqp);

reqsk_queue_removed(queue, req);

reqsk_free(req);

continue;

}

reqp = &req->dl_next;

}

i = (i+ 1) & (lopt->nr_table_entries- 1);

} while(--budget> 0);

lopt->clock_hand= i;

if (lopt->qlen)

inet_csk_reset_keepalive_timer(parent, interval);

}

那么TCP_DEFER_ACCEPT选项有什么好处呢,我们知道服务端处于监听时,客户端connect;服务端会收到syn包,并发送synack;当客户端收到synack并发送裸ack时,服务端accept创建一个新的句柄,这是不支持TCP_DEFER_ACCEPT选项下的流程。如果支持TCP_DEFER_ACCEPT,收到裸ack时,不会建立连接,操作系统不会Accept,也不会创建IO句柄。操作系统应该在若干秒后,会释放相关的链接;但没有同时关闭相应的端口,所以客户端会一直以为处于链接状态,如果Connect后面马上有后续的发送数据,那么服务器会调用Accept接收这个连接。

函数inet_csk_reqsk_queue_prune是通过tcp_synack_timer,是它在定时器中起作用的

static void tcp_synack_timer(struct sock*sk)

{

inet_csk_reqsk_queue_prune(sk, TCP_SYNQ_INTERVAL,

TCP_TIMEOUT_INIT, TCP_RTO_MAX);

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
管理系统,作为一种高效的企业运营管理工具,旨在通过集成化、系统化的手段,对组织内部的各类资源进行规划、协调、控制和优化,以实现企业战略目标,提升运营效率,增强核心竞争力。以下是对管理系统的详细介绍: 一、定义与构成 管理系统是指由硬件设备、软件应用、数据资源、人员以及相关管理制度共同构建的,用于处理、监控、分析和决策各类业务活动的综合信息系统。它通常包括以下几个核心组成部分: 数据采集模块:负责从各类业务环节中实时、准确地收集信息,形成企业的基础数据资源。 数据分析模块:运用统计学、人工智能等技术对数据进行深度挖掘和智能分析,提供决策支持。 业务流程管理模块:设计、执行、监控和优化业务流程,确保各项任务按照预定规则高效运转。 决策支持模块:基于数据分析结果,为管理者提供直观的可视化报告,辅助其进行科学决策。 用户界面与交互模块:提供友好的人机交互界面,方便用户操作使用。 二、主要类型与功能 管理系统根据所针对的管理对象和领域,可分为多种类型,如: 人力资源管理系统(HRM):涵盖招聘、培训、绩效考核、薪酬福利等人力资源全流程管理,提升人才效能。 客户关系管理系统(CRM):集中管理客户信息,优化销售、营销和服务流程,提升客户满意度和忠诚度。 供应链管理系统(SCM):整合供应商、制造商、分销商、零售商等供应链各环节,实现物流、资金流、信息流的协同运作。 企业资源计划系统(ERP):对企业内部财务、生产、采购、库存、销售等各项资源进行全面集成管理,提高整体运营效率。 项目管理系统(PM):对项目全生命周期进行规划、跟踪、控制,确保项目按时、按质、按预算完成。 三、价值与优势 提高效率:自动化工作流程、标准化业务操作,显著减少人工干预,提升工作效率。 优化决策:实时数据分析与预测,提供精准的决策依据,助力管理层做出明智选择。 资源整合:打破部门壁垒,实现信息共享,优化资源配置,降低运营成本。 合规风控:内置法规遵循机制,强化内部控制,降低经营风险。 持续改进:通过对系统数据的持续监控与分析,驱动业务流程持续优化,促进企业创新与发展。 总的来说,管理系统作为现代企业管理的重要工具,以其强大的数据处理能力、智能化的决策支持和高效的业务流程管理,有力推动了企业的数字化转型,助力企业在日益激烈的市场竞争中保持竞争优势。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值