赞
踩
协议实际上就是一种解决某些问题的策略和模式,在经典的TCP/IP协议中就有很多策略和模式值得学习。归纳起来有以下一些(随着学习深入逐步添加):
分层
分层是TCP/IP乃至网络通信最核心的策略和模式,分层使得所有的网络应用程序不用关心底层链路传输的细节,也使得不同类型的网络有效地互通。这是一种典型的化繁为简,把复杂的事情分解到不同层面的策略,层与层之间是服务与被服务的关系,每层只需关注所在维度的事情。例如,通过网络层IP协议的抽象和处理,把不同类型的网络互连起来,并且这些底层传输的差异对于上层(运输层和应用层)是透明的,这给上层应用程序的开发带来了极大的方便,示意图如下所示:
封装和分用
为了实现和支持上面说的分层策略,TCP/IP在数据包设计上采用封装和分用的策略,所谓封装就是在应用程序在发送数据的过程中,每一层都增加一些首部信息,这些信息用于和接收端同层次进行沟通,例如当数据从应用程序发送到以太网过程中数据逐层加工的示意图如下所示:
而在接收端的处理过程就正好相反,也就是所谓的分用策略,数据从底层到最上层的应用程序过程中,数据被逐层拆分,每一层取出自己所需要的信息。如下图所示:
可靠连接
TCP的可靠传输首先是建立在可靠的连接建立与关闭之上,这一块包含以下要点:
TCP三次握手建立连接
TCP为了通信双方确认建立起连接,设计了三次握手的策略,三次握手的过程如下:
1) 请求端发送一个SYN段指明客户打算连接的服务器的端口,以及初始序号(ISN)。
2) 服务器发回包含服务器的初始序号的SYN报文段作为应答。同时,将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。
3) 客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认
举一个实例:
为什么是三次握手?
对于这个问题,网络编程中的一个经典的规则也许能给一些提示:别人告诉你成功了那一定是成功了,没告诉你成功不一定是没成功。因此,如果是设计成两次握手,就有可能是被连接方第一次发出ack消息后,就处于成功建立连接的状态,但这条消息丢失了,主动连接方因为没有收到这个ack消息会认为建立连接失败,也许会放弃连接或启动新的连接,但被连接方会一直监听那个它误认为成功的连接。采用三次握手,前两次握手任何一次失败都会导致连接双方都处于未连接状态,第三次失败只会导致连接方处于成功状态,但做主动连接方,肯定会在连接不久后通过这个连接发送数据,这样就可以利用这个机制做进一步的容错。
通过tcpdump工具能很清晰地看到三次握手的过程,先在主机B(itbu_qa17)上打开tcpdump监控
/usr/local/sbin/tcpdump port 80 and host 10.19.14.1
然后主机A(10.19.14.1) telnet到主机B,tcpdump监控结果如下:
TCP半关闭
TCP半关闭时TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。因此,连接关闭的过程需要连接双方都要发起关闭连接的消息,示意图如下所示:
为什么要设计成半关闭?
设计成半关闭主要是存在无需发送数据,只需接收数据的需求,并且可以通过发起单方面的关闭请求标志已发送数据完成。如果没有半关闭的需求,就得建立两个连接。
通过tcpdump工具能很清晰地看到三次握手的过程,主机A(10.19.14.1) telnet到主机B,然后在主机B(itbu_qa17)上打开tcpdump监控
/usr/local/sbin/tcpdump port 80 and host 10.19.14.1
然后主机A关闭telnet,tcpdump监控结果如下:
TCP的状态变迁
连接双方从新建连接到建立连接再到关闭连接,会经历一些状态,这些状态在分析问题时非常重要,状态变迁全景图如下所示:
就连接双方的建立连接和关闭连接过程来看,状态变迁序列图如下所示:
TCP服务端监听和处理设计
TCP服务端一般设计为连接建立后一个进程监听端口,当一个新的连接请求到达服务器时,服务器接受这个请求,并调用一个新进程来处理这个新的客户请求。以telnet为例,使用netstat查看服务端监听状态为LISTEN,如下图所示:
当有客户端telnet过来时,监听进程会起另外的进程来处理,如下图所示:
TCP的可靠传输首先是建立在可靠的连接建立与关闭之上,这一块包含以下要点:
TCP三次握手建立连接
TCP为了通信双方确认建立起连接,设计了三次握手的策略,三次握手的过程如下:
1) 请求端发送一个SYN段指明客户打算连接的服务器的端口,以及初始序号(ISN)。
2) 服务器发回包含服务器的初始序号的SYN报文段作为应答。同时,将确认序号设置为客户的ISN加1以对客户的SYN报文段进行确认。一个SYN将占用一个序号。
3) 客户必须将确认序号设置为服务器的ISN加1以对服务器的SYN报文段进行确认
举一个实例:
为什么是三次握手?
对于这个问题,网络编程中的一个经典的规则也许能给一些提示:别人告诉你成功了那一定是成功了,没告诉你成功不一定是没成功。因此,如果是设计成两次握手,就有可能是被连接方第一次发出ack消息后,就处于成功建立连接的状态,但这条消息丢失了,主动连接方因为没有收到这个ack消息会认为建立连接失败,也许会放弃连接或启动新的连接,但被连接方会一直监听那个它误认为成功的连接。采用三次握手,前两次握手任何一次失败都会导致连接双方都处于未连接状态,第三次失败只会导致连接方处于成功状态,但做主动连接方,肯定会在连接不久后通过这个连接发送数据,这样就可以利用这个机制做进一步的容错。
通过tcpdump工具能很清晰地看到三次握手的过程,先在主机B(itbu_qa17)上打开tcpdump监控
/usr/local/sbin/tcpdump port 80 and host 10.19.14.1
然后主机A(10.19.14.1) telnet到主机B,tcpdump监控结果如下:
TCP半关闭
TCP半关闭时TCP提供了连接的一端在结束它的发送后还能接收来自另一端数据的能力。因此,连接关闭的过程需要连接双方都要发起关闭连接的消息,示意图如下所示:
为什么要设计成半关闭?
设计成半关闭主要是存在无需发送数据,只需接收数据的需求,并且可以通过发起单方面的关闭请求标志已发送数据完成。如果没有半关闭的需求,就得建立两个连接。
通过tcpdump工具能很清晰地看到三次握手的过程,主机A(10.19.14.1) telnet到主机B,然后在主机B(itbu_qa17)上打开tcpdump监控
/usr/local/sbin/tcpdump port 80 and host 10.19.14.1
然后主机A关闭telnet,tcpdump监控结果如下:
TCP的状态变迁
连接双方从新建连接到建立连接再到关闭连接,会经历一些状态,这些状态在分析问题时非常重要,状态变迁全景图如下所示:
就连接双方的建立连接和关闭连接过程来看,状态变迁序列图如下所示:
TCP服务端监听和处理设计
TCP服务端一般设计为连接建立后一个进程监听端口,当一个新的连接请求到达服务器时,服务器接受这个请求,并调用一个新进程来处理这个新的客户请求。以telnet为例,使用netstat查看服务端监听状态为LISTEN,如下图所示:
当有客户端telnet过来时,监听进程会起另外的进程来处理,如下图所示:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。