tcp与udp特点,三次握手四次挥手

一TCP、UDP区别

1共同点:传输层协议,传输信息

2区别:

TCP传输控制协议UDP用户数据包协议
可靠性可靠不可靠
 连接性 面向连接 无连接
 报文 面向字节流 面向报文
 效率 传输效率低 传输效率高
 双工性 全双工 一对一、一对多、多对一、多对多
 流量控制 有(滑动窗口) 无
 拥塞控制 有(慢开始、拥塞避免、快重传、快恢复) 无

tcp:面向连接,可靠,开销小,传输效率低,延时高,端到端传输

udp:无连接,不可靠,开销大,传输效率高,一对一、一对多、多对一、多对多

tcp有拥塞控制,可以慢开始,拥塞避免,快重传,快恢复。udp没有拥塞控制,不管网络是否拥塞,udp客户端都可以一直发送。

tcp适用于数据传输准确度要求度高的场合(电话)。udp适用于数据传输量大,实时性要求高的场合(短信)

tcp数据完整,按时,按序到达。udp尽最大努力交付数据。

二tcp如何保证可靠传输

TCP通过序列号、数据包检验、确认应答机制、超时重发、连接管理、流量控制、拥塞控制实现可靠性。

  • 校验和: TCP在发送报文之前,发送方要计算校验和,收到数据后,接收方也要计算校验和,如果校验和不相等则丢弃。

  • 序列号与确认应答:

    • 序列号:TCP传输时将每个字节的数据都进行了编号,这就是序列号。

    • 确认应答:TCP传输的过程中,每次接收方收到数据后,都会对传输方进行确认应答。也就是发送ACK报文。这个ACK报文当中带有对应的确认序列号,告诉发送方,接收到了哪些数据,下一次的数据从哪里发。

    • 序列号的作用不仅仅是应答的作用,有了序列号能够将接收到的数据根据序列号排序,并且去掉重复序列号的数据。这也是TCP传输可靠性的保证之一。

  • 超时重传: 在TCP传输过程中,我们在发送一部分数据后,都会等待对方的ACK确认报文,如果中间出现差错,没有收到ACK报文,这时候需要启动超时重传机制。这种超时重传机制保证了TCP在网络延迟或者报文丢失下的可靠传输。

    超时的原因:

    • 接收方没有收到TCP报文段:网络延迟或者丢包;

    • 发送方没有收到ACK报文段:网络延迟或者ACK报文丢失。

  • 连接管理:连接管理就是三次握手与四次挥手的过程(后面有详细解释)

  • 流量控制: 流量控制的目的是让接收方来得及接收数据。这样避免了数据丢包以及网络拥塞等情况。

  • 拥塞控制: 拥塞控制就是防止过多的数据注入到网络中,这样使网络中的路由器或者链路不至于过载。

  • 三拥塞控制详解

  • TCP通过慢启动、拥塞避免、快重传以及快恢复这四个算法来进行拥塞控制

    • 慢启动:一开始先设置一个比较小的拥塞窗口值cwnd(报文段的倍数),然后进行数据传输,每收到一个报文段的确认,我们就将cwnd+1,这样下来,cwnd总体上是乘以2^n的倍数增长。(慢启动非增长速度慢,只是增长的初始基数比较小)

    • 拥塞避免: 因为慢启动算法的增长比较快,当cwnd = ssthresh(预先设置好的门限值)时,我们启动拥塞避免算法,窗口值开始线性增长

    随着拥塞避免算法的进行,网络出现超时的情况(这时判断为拥塞出现)。这时将cwnd降为一开始的值,重新进行慢开始-拥塞避免,并且此时的门限值设为出现拥塞时的cwnd的一半。

    • 快重传: 快重传的目的是为了让发送方尽早知道某个报文段的丢失。如何知道呢?当我们重复收到某一个报文段的3次确认时,我们就可以判断,它的下一个报文段可能出现了丢失。这时我们启动快重传算法,立即重传丢失的报文段。

    • 快恢复: 上面快重传算法的启动只是因为个别报文段的丢失,我们这时并不判断为网络拥塞,而是启动快恢复算法。我们将cwnd=ssthresh=当前cwnd的一半,并且开始拥塞避免算法。

    当然,也有的快恢复算法是将当前拥塞窗口再增大3个报文段的值,因为既然收到了3个重复的ACK,则说明有三个分组已经离开了网络,不在占用网络资源而是停留在对方缓存当中,可以适当将窗口值增大。

四udp的问题

丢包与无序

如何解决丢包问题:  增大接收端的缓冲区大小;       增大接收端的处理能力;

无序:修改协议,增加超时重发,确认机制

五三次握手
       

所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。

1.TCP 为什么三次握手而不是两次握手

1.防止已失效的连接请求又传送到服务器端,因而产生错误。不太准确

  为了实现可靠数据传输, TCP 协议的通信双方, 都必须维护一个序列号, 以标识发送出去的数据包中, 哪些是已经被对方收到的。 三次握手的过程即是通信双方相互告知序列号起始值, 并确认对方已经收到了序列号起始值的必经步骤。如果只是两次握手, 至多只有连接发起方的起始序列号能被确认, 另一方选择的序列号则得不到确认。

在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:


                     图1 TCP三次握手

        (1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
        (2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1(确认号码),随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
        (3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
        
     ①   SYN攻击:
                在三次握手过程中,Server发送SYN-ACK之后,收到Client的ACK之前的TCP连接称为半连接(half-open connect),此时Server处于SYN_RCVD状态,当收到ACK后,Server转入ESTABLISHED状态。SYN攻击就是Client在短时间内伪造大量不存在的IP地址,并向Server不断地发送SYN包,Server回复确认包,并等待Client的确认,由于源地址是不存在的,因此,Server需要不断重发直至超时,这些伪造的SYN包将产生时间占用未连接队列导致正常的SYN请求因为队列满而被丢弃,从而引起网络堵塞甚至系统瘫痪。SYN攻击时一种典型的DDOS攻击,检测SYN攻击的方式非常简单,即当Server上有大量半连接状态且源IP地址是随机的,则可以断定遭到SYN攻击了,使用如下命令可以让之现行:
                #netstat -nap | grep SYN_RECV
 

六 四次挥手


         所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:


                               图2 TCP四次挥手

        由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
        (1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
        (2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
        (3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
        (4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
        上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况,具体流程如下图:

                                      图3 同时挥手

      

①第四次挥手客服端为什么要等待2MSL时间?

去向ACK消息最大存活时间(MSL) + 来向FIN消息的最大存活时间(MSL)。

这恰恰就是2MSL( Maximum Segment Life)。

      1.  当客户端的最后一次确认连接的报文丢失(第四次挥手发送的),服务器会再次发送FIN报文,等待客户端的确认,客户端在2MSL内收到服务器重传的报文再次确认(防止此时客户端已经关闭)。安心的释放tcp占用的资源,端口

      2.  2MSL 的时间可以使所有已失效的报文都消失(防止对新建的连接造成影响),若在不等待2MSL,马上建立新的连接,那么在关闭连接前发送的失效报文段很可能影响本次连接如果不等,释放的端口可能会重连刚断开的服务器端口,这样依然存活在网络里的老的TCP报文可能与新TCP连接报文冲突,造成数据冲突

   然而,TCP规定处于2MSL状态的的插口对(客户端IP/端口和服务器IP和端口)不能再次被使用。 若在2MSL状态下新建连接可以使用这个插口对,当已失效的数据包再次到达这个新连接,判断插口一致就会接受这个报文,但实际上这不是新建连接交互的数据,因此不能使用此无效数据包。


七    为什么建立连接是三次握手,而关闭连接却是四次挥手呢?


        这是因为服务端在LISTEN状态下,收到建立连接请求的SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文时,仅仅表示对方不再发送数据了但是还能接收数据,己方也未必全部数据都发送给对方了,所以己方可以立即close,也可以发送一些数据给对方后,再发送FIN报文给对方来表示同意现在关闭连接,因此,己方ACK和FIN一般都会分开发送。

TCP传输信息

客户端:①创建socket,链接远端地址

②连接后发送数据和接收数据

③传输完毕,关闭socket

import socket
s=socket.socket()
host=10.0.0.0
port=123
s.connect(host,port)
print(s.recv(1024)
s.close()

服务端:①创建socket,绑定socket到本地ip与端口

②开始监听连接

③进入循环不断接收客户端的连接请求

④接受传来的数据,发送数据给对方

⑤传输完毕,关闭socket

import socket
s=socket.socket()
host=10.0.0.0
port=123
s.bind(host,port)

s.listen(5)
while True:
    c,addr=s.accept()
    print(addr)
    c.send("hello")
    c.close()

 

UDP传输信息

客户端:①创建socket,链接远端地址

②发送数据和接收数据

③传输完毕,关闭socket

import socket
s=socket.socket()
host=10.0.0.0
port=123
addr=(host,port)
data=input("the data you need to send:")
s.sendto(data.encode(),addr)
s.close()

服务端:①创建socket,绑定socket到本地ip与端口

②开始监听连接

③进入循环不断接收客户端的连接请求

④等待对方发送数据,接受传来的数据,

⑤传输完毕,关闭socket

import socket
s=socket.socket()
host=10.0.0.0
port=123
s.bind(host,port)
data=input("data:")
s.sendto(data.encode(),addr)
receive_data=s.recvfrom(1024)
s.close()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值