当前位置:首页 > 嵌入式 > 嵌入式软件
[导读] 在tcp_v4_do_rcv中,有下面一段代码,是关于TCP连接建立时候的代码:if (sk->sk_state == TCP_LISTEN) {struct sock *nsk = tcp_v4_hnd_req(sk, skb);if (!nsk)goto disca

 在tcp_v4_do_rcv中,有下面一段代码,是关于TCP连接建立时候的代码:

if (sk->sk_state == TCP_LISTEN) {

struct sock *nsk = tcp_v4_hnd_req(sk, skb);

if (!nsk)

goto discard;

if (nsk != sk) {

if (tcp_child_process(sk, nsk, skb))

goto reset;

return 0;

}

}

tcp_v4_hnd_req的返回值,不同情况下不同。

NULL 出现错误

nsk==sk 接受到SYN

nsk!=sk 接受到ACK

接受到ACK包时,tcp_v4_hnd_req函数会新建一个sock结构,并设置其初始状态为SYN_RECV,并返回新建的sock结构。

接着调用tcp_child_process函数,改变新建的sock的状态为ESTABLISHED。

(以下基于linux内核2.4.0)

SYN_RECV状态,顾名思义,是收到SYN包后应该置的状态。关于SYN_RECV状态,受某些教科书的误导,我以前一直理解为服务器收到SYN包后应该置此状态。也没细想到底是置那个socket的状态,最近在看三次握手协议在linux内核中的实现时,才仔细思考这个问题应该是置连接套接字的状态而非监听套接字的状态。

通常,SYN包只用于TCP三次握手协议中。常见的tcp三次握手协议过程(当然还有同时连接)

半连接等其它一些情况)如下:

1、client SYN包---> server

2、client <---SYN包/ACK包 server

3、client ACK包---> server

根据tcp状态图,对应下述4个状态的变化

a、client发送完毕,状态变成SYN_SEND;

b、server收到SYN报并发送ack确认包和SYN包,状态变为SYN_RECV

c、client发送ack包完毕,状态变成ESTABLISHED

d、server发送ack包完毕,状态变成ESTABLISHED

在linux内核中,上述几个状态对应为TCP_SYN_SEND、TCP_SYN_RECV、TCP_ESTABLISHED.

RFC793中关于SYN_RECV状态的描述如下:

SYN-RECEIVED - represents waiting for a confirming connection

request acknowledgment after having both received and sent a

connection request.

从上面可以看出,这个状态是在本端接收到对端连接请求,并发送连接对端请求后,等待对端应答时所置的状态。所以,本质上连接的过程是双方请求应答的来回, 应该称四次握手,只是常见的应用以c/s模式为主,而linux、包括绝大部分操作系统都把服务器端的应答和请求封装在一个包里面。

但在linux内核中,却是在监听套接字收到了客户端的ACK包后,才创建连接套接字并初始化为TCP_SYN_RECV状态,如下函数调用关系:

tcp_v4_rcv-->tcp_v4_do_rcv-->tcp_v4_hnd_req-->tcp_check_req-->

tcp_v4_syn_recv_sock-->tcp_create_openreq_child...

struct sock *tcp_create_openreq_child(struct sock *sk, struct open_request *req, struct sk_buff *skb)

{

struct sock *newsk = sk_alloc(PF_INET, GFP_ATOMIC, 0); /*创建连接sock结构*/

if(newsk != NULL) {

struct tcp_opt *newtp;

...

memcpy(newsk, sk, sizeof(*newsk));

newsk->state = TCP_SYN_RECV; /*置初始状态为SYN_RECV*/

//以下为一些初始化newsk结构的操作

...

}

这里似乎都正常了,但还有一点,服务器收到ACK包后,状态应该改为连接状态,而此时连接套接字的状态还是TCP_SYN_RECV

原因在于现在对ack包还没处理完,^_^,如下:

int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb)

{

...

if (sk->state == TCP_LISTEN) { //此处是监听套接字的状态

struct sock *nsk = tcp_v4_hnd_req(sk, skb); //获得了上面讲的连接套接字

if (!nsk)

goto discard;

if (nsk != sk) { //显然监听与连接套接字不等

if (tcp_child_process(sk, nsk, skb)) //此处调用tcp_rcv_state_process置套接字为连接建立状态

goto reset;

return 0;

}

}

...

}

可见,在linux内核中,SYN_RECV状态的保持时间是非常短暂的(也很难创建条件让此状态保持),这也是我们实际应用中通过netstat基本看不到这个状态的原因。

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

深圳2023年9月15日 /美通社/ -- 9月14-15日,2023全球AI芯片峰会(GACS 2023)在深圳正式举行。峰会以【AI 大时代 逐鹿芯世界】为主题,共探AI芯片的产学研用,邀请了清华大学教授、中国半导体...

关键字: 接口 芯科 内存 AC

成都2023年9月5日 /美通社/ -- 2023年9月5日,ACCA市场关系执行总监卢曦(Lucia)、ACCA中国总监梁淑萍一行到访成都,就推动财金大学生职业发展议题与实习僧展开交流。双方正式签署"ACCA...

关键字: AC 创始人 AI LEARNING

上海2023年9月4日 /美通社/ -- 2023年8月25日,由杜塞尔多夫展览(上海)有限公司主办且首次引入中国市场的2023康复设备与解决方案展览会(REHACARE CHINA)在苏州国际博览中心圆满落下帷幕。...

关键字: CHINA AC INTERNATIONAL BSP

香港2023年8月30日 /美通社/ -- 全球领先的互联网社区创建者—网龙网络控股有限公司("网龙"或"本公司";香港交易所股份代号...

关键字: BSP TI PANEL AC

昆明2023年8月30日 /美通社/ -- 8月25日晚间,沃森生物发布2023年半年报。报告显示,2023年上半年公司实现营业收入21.68亿元,归属于上市公司股东净利润4.55亿元,同比增长8.13%;报告期内,公司...

关键字: HP AC 管线 DAS

苏州2023年8月29日 /美通社/ -- 8月28日晚,协鑫能科公告,下属控股子公司年产20GWh储能系统项目在张家港经济技术开发区投产。这标志着协鑫集团正式完成从上游储能...

关键字: AC CK 电力系统 电源

美国罗克维尔和中国苏州2023年8月17日 /美通社/ -- 信达生物制药集团(香港联交所股票代码:01801),一家致力于研发、生产和销售肿瘤、自身免疫、代谢、眼科等重大疾病领域创新药物的生物制药公司,今日宣...

关键字: PC AC TE GO

上海2023年8月14日 /美通社/ -- 为助力中国康复产业发展,杜塞尔多夫展览集团公司通过子公司杜塞尔多夫展览(上海)有限公司在中国引入全新展会 -- 康复设备与解决方案展览会(REHACARE CHINA),以“融...

关键字: AC CHINA 助听器 黑科技

谢霆锋惊喜空降首发现场 南京2023年8月10日 /美通社/ -- 创新无止境,8月9日,一场以"始见•未止"为主题的发布会在上海拉法耶艺术设计中心隆重举行。发布会现场,西门子家电品牌代言人谢霆锋与...

关键字: STUDIO 西门子 COO AC

马来西亚吉隆坡2023年8月7日 /美通社/ -- 近期,由行业知名展会iFX EXPO主办方Ultimate Fintech举办的2023年亚太区终极金融科技奖 (UF AWARDS APAC 2023)于日前落下帷幕...

关键字: AC AN BSP ULTIMATE
关闭
关闭