TCPvsUDP详解及其区别
TCPvsUDP详解及其区别
本文重要收集了UDP和TCP的概念以及连接的建立过程:
UDP:用户数据报协议
广播和多播仅应用于U D P,它们对需将报文同时传往多个接收者的应用来说十分重要。T C P是一个面向连接的协议,它意味着分别运行于两主机(由I P地址确定)内的两进程(由端口号确定)间存在一条连接。
然而,有时一个主机要向网上的所有其他主机发送帧,这就是广播。通过A R P和R A R P可以看到这一过程。多播(multicast) 处于单播和广播之间:帧仅传送给属于多播组的多个主机。
对于以太网,当地址中最高字节的最低位设置为1时表示该地址是一个多播地址,
用十六进制可表示为0 1 : 0 0 : 0 0 : 0 0 : 0 0 : 0 0(以太网广播地址ff: ff : ff : ff : ff : ff可看作是以太网多播地址的特例)。
如果需要了解更多关于多播和广播的知识请参考TCP/IP协议中的广播和多播一章。
我们称UDP提供无连接服务,因为UDP客户与服务器不必存在长期的关系。例如:一个UDP客户可以创建一个套接口并发送一个数据报给一个服务器,然后立即用同一个套接口发送另一个数据报给另一个服务器。同样,一个UDP服务器可以用用以个UDP套接口从5个不同的客户一连串接受5个数据报。
UDP套接口编程:
客户不与服务器建立连接,它只管用函数sendto给服务器发送数据报,此函数要求目的地址(服务器)作为其参数。类似的,服务器不从客户接受连接,它只管调用函数recvfrom,等待来自其客户的数据到达。与数据报一起,recvfrom返回客户的协议地址,所以服务器可以发送响应给正确的客户。
UDP的connect函数:
我们可以给UDP套接口调用connect,但这样做的结果却与TCP连接豪不相同;没有三路握手过程。内核至少记录对方的IP地址和端口号,它们包含在传递给connect套接口地址结构中,并立即返回给调用进程。
一般来说,都是UDP客户调用connect,但也有udp服务器与单个客户长时间通信的应用程序(如TFTP),在这种情况下,客户和服务器都可调用connect.
给一个UDP套接口多次调用connect
对于已连接UDP套接口,进程可给那个套接口再次调用connect以达到下面两个目的之一:
指定新的IP地址和端口号;
断开套接口;
与TCP套接口中connect的使用有所不同:只可给TCP套接口调用一次connect;
在未连接UDP套接口上给两个数据报调用函数sendto导致内核执行下列六步:
连接套接口;
输出第一个数据报;
断开套接口连接;
连接套接口;
输出第二个数据报;
断开套接口连接。
调用connect,然后调用两次write,导致内核执行如下步骤:
连接套接口;
输出第一个数据报;
输出第二个数据报;
Tr a c e r o u t e程序,RIP程序都会用到UDP程序
TCP:传输控制协议
尽管T C P和U D P都使用相同的网络层(I P),T C P却向应用层提供与UD P完全不同的服务。T C P提供一种面向连接的、可靠的字节流服务。
每个T C P段都包含源端和目的端的端口号,用于寻找发端和收端应用进程。这两个值加上I P首部中的源端I P地址和目的端I P地址唯一确定一个TC P连接。
T C P将用户数据打包构成报文段;它发送数据后启动一个定时器;另一端对收到的数据进行确认,对失序的数据重新排序,丢弃重复数据;T C P提供端到端的流量控制,并计算和验证一个强制性的端到端检验和。
TCP连接的建立和终止
首先,TCP提供客户与服务器的连接;
其次,TCP提供可靠性;
第三,TCP通过给所发送数据的每一个字节关联一个序列号进行排序;
第四,TCP提供流量控制;TCP总是告诉对方它能够接受多少字节的数据,这称为通告窗口。
最后,TCP连接时全双工的;
为了建立一条T C P连接:
1) 请求端(通常称为客户)发送一个S Y N段指明客户打算连接的服务器的端口,以及初始序号(I S N,在这个例子中为1 4 1 5 5 3 1 5 2 1)。这个S Y N段为报文段1。
2) 服务器发回包含服务器的初始序号的S Y N报文段(报文段2)作为应答。同时,将确认序号设置为客户的I S N加1以对客户的S Y N报文段进行确认。一个S Y N将占用一个序号。
3) 客户必须将确认序号设置为服务器的I S N加1以对服务器的S Y N报文段进行确认(报文段3)。
这三个报文段完成连接的建立。这个过程也称为三次握手(three-wayhandshake)。
为什么需要三次握手:
一是为了可靠请看《计算机网络》P26,经典例子,不可能设计出100%可靠的协议,二是为了防止已失效的连接请求突然又传送到了服务器,因而产生错误。
建立一个连接需要三次握手,而终止一个连接要经过4次握手。这由T C P的半关闭(h a l f -c l o s e)造成的。既然一个T C P连接是全双工(即数据在两个方向上能同时传递),因此每个方向必须单独地进行关闭。这原则就是当一方完成它的数据发送任务后就能发送一个F I N来终止这个方向连接。当一端收到一个F I N,它必须通知应用层另一端几经终止了那个方向的数据传送。发送F I N通常是应用层进行关闭的结果。
建立一个TCP连接时,会发生下述情形:
1、服务器端必须做好准备接受外来的连接。这通常通过 socket(), bind(), listen() 三个函数来完成的。我们称之为 被动打开(passive open).
2、客户端通过调用connect发起主动打开(active open)。这导致客户端TCP发送SYN同步分节。它告诉服务器客户端在(待建立的)连接中发送的数据的初始化序列号。通用SYN分节不携带数据,
3、服务器必须确认(ACK) 客户端的SYN,同时自己也得发送一个SYN分节,它含有服务器将在统一连接中发送的数据的初始化序号。服务器在单个分节中发送SYN和对客户端SYN的ACK确认。
4、客户端必须确认服务器的SYN。
建立TCP连接的日常系统类比是电话系统[Nemeth 1997].socket函数等同于有电话可用.bind用于告诉其他人你的电话号码,让他们可以向你打电话.listen是打开电话振铃,它使你可以听到一个外来的电话.connect要求你知道另一方的电话号码并拨打它.accept是被呼叫回电话.从accept返回客户的标识(即客户的IP地址和端口号)类似于让电话机的呼叫者ID功能部件显示打电话人的电话号码.然而有点不同的地方是:从accept返回客户的标识是在建立连接以后,而呼叫者ID功能部件显示打电话人的电话号码是在我们选择接或不接电话之前.如果使用域名系统(第9章),那么提供了一种类似于电话薄的服务.gethostbyname类似于在电话薄查找个人的电话号码.gethostbyaddr则类似于有一种电话薄按电话号码排序
SYN洪水攻击
假设一个C向S发送了SYN后无故消失了,那么S在发出SYN+ACK应答报文后是无法收到C的ACK报文的(第三次握手无法完成),这种情况下S一般会重试(再次发送SYN+ACK给客户端)并等待一段时间后丢弃这个未完成的连接,这段时间的长度我们称为SYN Timeout,一般来说这个时间是分钟的数量级(大约为30秒-2分钟);一个C出现异常导致S的一个线程等待1分钟并不是什么很大的问题,但如果有一个恶意的攻击者大量模拟这种情况,S将为了维护一个非常大的半连接列表而消耗非常多的资源----数以万计的半连接,即使是简单的保存并遍历也会消耗非常多的CPU时间和内存,何况还要不断对这个列表中的IP进行SYN+ACK的重试.实际上如果S的TCP/IP栈不够强大,最后的结果往往是堆栈溢出崩溃---即使S的系统足够强大,S也将忙于处理攻击者伪造的TCP连接请求而无暇理睬客户的正常请求(毕竟C的正常请求比率非常之小),此时从正常客户的角度看来,S失去响应,这种情况我们称作:服务器端受到了SYN Flood攻击(SYN洪水攻击).
TCP连接的终止:
1、某个应用程序首先调用close,主动关闭(active close) 该端的TCP于是发送一个FIN分节,表示数据发送完毕。
2、接收到这个FIN的对端执行被动关闭(passive close)。这个FIN是TCP确认。它的接收也作为一个文件结束符(end of file) 传递给接收端的应用程序(放在排队等候应用进程接收的任何其他数据之后),因为FIN的接收意味着接收端应用程序在相应连接上再无额外数据可以接收。
3、一段时间以后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN。
4、接收这个最终FINd额原发送端TCP(即执行主动关闭的一端)确认这个FIN
注意:执行主动关闭的那一端(客户端)进入TIME_WAIT状态。
TIME_WAIT状态:
TCP中有关网络编程最不容易理解的是它的TIME_WAIT状态。执行主动关闭的那端进入这种状态,该端点停留在这种状态的持续时间是最长分节生命周期(MSL)的两倍,有时候称之为2MSL。
存在TIME_WATI状态有两个理由:
1、可靠地实现TCP全双工连接的终止。
2、允许老的重复分节在网络中消逝。
第一个理由的解释如下:假设TCP连接终止的最终的ACK丢失,服务器将重发最终的FIN,因此客户必需维护状态信息,以允许它重发最终的ACK。要是不维护状态信息,它将响应以RST,而服务器则把该分节解释成一个错误。
要理解存在TIME_WAIT状态的第二个理由,我们假设在12.106.32.254的端口1500和206.168.112.219的端口21之间有一个TCP连接。我们关闭这个连接后,在以后某个时候又重新建立起相同的IP和端口之间的TCP连接。后一个连接称为前一个连接的化身,因为它的IP地址和端口号都相同。TCP必须防止来自某个连接的老的重复分组在该链接已经终止后再现,从而被误解成属于同一连接的新化身。为做到这一点,TCP将不给处于TIME_WAIT状态的连接启动新的化身。既然TIME_WAIT状态持续的时间是2MSL,这就足够允许某个方向上的分组最多存活MSL秒即被丢弃,另一个方向上的应答最多存活MSL秒也被丢弃。通过实施这个规则,我们能够保证每当成果建立一个TCP连接时,来自该连接先前化身的老的重复分组都已在网络中消逝。
TCP套接口编程:
上一篇: TCP的推送比特PSH(Push)
下一篇: DOS下重启网卡