|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
常用的linux命令,尤其是一些能帮你提高开发效率的命令,(eg:grep,awk,sed,split等);
在tcp_v4_do_rcv中,有上面一段代码,是关于TCP毗连创建时分的代码:
if(sk->sk_state==TCP_LISTEN){
structsock*nsk=tcp_v4_hnd_req(sk,skb);
if(!nsk)
gotodiscard;
if(nsk!=sk){
if(tcp_child_process(sk,nsk,skb))
gotoreset;
return0;
}
}
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、clientSYN包――>server
2、client<――SYN包/ACK包server
3、clientACK包――>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-representswaitingforaconfirmingconnection
requestacknowledgmentafterhavingbothreceivedandsenta
connectionrequest.
从下面能够看出,这个形态是在本端吸收到对端毗连哀求,并发送毗连对端哀求后,守候对端应对时所置的形态。以是,实质上毗连的历程是两边哀求应对的往返,应当称四次握手,只是罕见的使用以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……
structsock*tcp_create_openreq_child(structsock*sk,structopen_request*req,structsk_buff*skb)
{
structsock*newsk=sk_alloc(PF_INET,GFP_ATOMIC,0);/*创立毗连sock布局*/
if(newsk!=NULL){
structtcp_opt*newtp;
……
memcpy(newsk,sk,sizeof(*newsk));
newsk->state=TCP_SYN_RECV;/*置初始形态为SYN_RECV*/
//以下为一些初始化newsk布局的操纵
……
}
这里仿佛都一般了,但另有一点,服务器收到ACK包后,形态应当改成毗连形态,而此时毗连套接字的形态仍是TCP_SYN_RECV
缘故原由在于如今对ack包还没处置完,^_^,以下:
inttcp_v4_do_rcv(structsock*sk,structsk_buff*skb)
{
……
if(sk->state==TCP_LISTEN){//此处是监听套接字的形态
structsock*nsk=tcp_v4_hnd_req(sk,skb);//取得了下面讲的毗连套接字
if(!nsk)
gotodiscard;
if(nsk!=sk){//明显监听与毗连套接字不等
if(tcp_child_process(sk,nsk,skb))//此处挪用tcp_rcv_state_process置套接字为毗连创建形态
gotoreset;
return0;
}
}
……
}
可见,在linux内核中,SYN_RECV形态的坚持工夫长短常长久的(也很难创立前提让此形态坚持),这也是我们实践使用中经由过程netstat基础看不到这个形态的缘故原由
</p>
在linux中学习命令的最好办法是学习Shell脚本编程,Shell脚本比起其他语言来学习简单,但是功能却十分强大.通过学习Shell编程,能让你掌握大量的linux命令。 |
|