zoukankan      html  css  js  c++  java
  • 【UNIX网络编程】传输层:TCP、UDP和SCTP

    UDP(User Datagram Protocol,用户数据报协议):

    1. 不可靠的:不保证UDP数据报会到达其最终目的地,不保证各个数据报的先后顺序跨网络后保持不变,不保证每个数据报只到达一次
    2. 数据报模式:每一个UDP数据报都有一个长度,如果一个数据报正确到达目的地,那么该数据报长度将随数据一道床底给接收端应用进程(有记录边界,不同于TCP)
    3. 无连接的:UDP客户与服务器不必存在任何长期的关系,一个UDP客户可以创建一个套接字发送一个数据报给一个服务器,然后立即用同一个套接字发送另一个数据报给另一个服务器,同理,UDP服务器也可以用同一个套接字接收不同客户的数据报

    TCP(Transmission Control Protocol,传输控制协议):

    1. 面向连接的:TCP客户先与某个给定服务器建立一个连接,再跨这个连接与那个服务器交换数据,然后终止这个连接。
    2. 可靠的:TCP向另一端发送数据时,要求对端返回一个确认。如果没有收到确认,TCP就自动重传数据并等待更长时间。在数次重传失败之后,TCP才放弃(尝试发送的总时间依赖于具体实现)。TCP提供的是数据的可靠递送或故障的可靠通知(通过放弃重传并中断连接)。
    3. 字节流模式:没有任何记录边界,因此不确定一次返回了多少数据,所以在TCP套接字读取数据时,需要将读取函数写在某个循环中
    4. TCP的一些特点:
      1. TCP含有用于动态估算客户和服务器之间的往返时间(round-trip time , RTT)的算法,以便它知道等待一个确认需要多少时间。RTT受网络流通各种变化因素影响,TCP还持续估算一个给定连接的RTT。
      2. TCP通过给其中每个字节关联一个序列号对所发送的数据进行排序(sequencing)。假设一个2048字节的数据分为2个“分节”(分节是TCP传递给IP的数据单元)发送,如果这些分节不是顺序到达,或者某个分节由于网络拥挤导致重复数据,接收端TCP将先根据它们的序列号重新排序,并丢弃重复数据。(UDP不提供可靠性,所以没有确认、序列号、RTT估算、超时和重传等机制,但是UDP应用必须处理颠倒、重复等所有这些异常情况)
      3. TCP提供流量控制(flow control),TCP总是告知对端在任何时刻它一次能够从对端接收多少字节的数据,这称为通告窗口(advertised window)。该窗口指出接收缓冲区中当前可用的空间量,从而确保发送端发送的数据不会使接收缓冲区溢出。(当应用不从缓冲区读取数据的时候,窗口大小可能减小到0)。(同样地,UDP不提供流量控制)
      4. TCP连接是全双工的(full-duplex),在一个给定的连接上,应用可以在任何时刻在进出两个方向上既发送数据又接收数据。因此,TCP必须为每个数据流方向跟踪诸如序列号和通告窗口大小等状态信息。

    SCTP(Stream Control Transmission Protocol,流控制传输协议):SCTP在客户和服务器之间提供关联(association),并像TCP那样给应用提供可靠性、排序、流量控制以及全双工的数据传送。此处注意“关联”和“连接”,“连接”只涉及两个IP地址之间的通信,“关联”指代两个系统之间的一次通信,SCTP支持多宿而涉及不止两个地址(单个SCTP断电能够支持多个IP地址,如果它的某个网络或某个跨越因特网的桐庐发送故障,SCTP就可以通过切换到使用已经与该关联相关的另一个地址来规避所发生的故障)。SCTP是面向信息的(message-oriented)。它提供各个记录的按序递送服务,与UDP一样,由发送端写入的每条记录的长度随数据一道传递给接收端应用。SCTP能够在所连接的端点之间提供多个流,每个流各自可靠地按序递送消息。一个流上某个消息的丢失不会阻塞同一关联其他流上消息的投递。TCP而言,在单一字节流中任何位置的字节丢失都将阻塞该连接上其后所有数据的递送,直到该丢失被修复为止。

    TCP的建立和终止

    1. 三次握手(需要3个分节的交换才可以完成TCP的连接)的过程描述:
      1. 服务器必须准备好接收外来的连接,这通过调用socket,bind和listen这3个函数来完成,我们称之为被动打开(passive open) -> 这里还没有开始握手
      2. 客户通过调用connect发起主动打开(active open)。这导致客户TCP发送一个SYN(同步)分节,它告诉服务器客户将在(待建立的)连接中发送的数据的初始序列号。通常SYN分节不携带数据,其所在IP数据报只含有一个IP首部、一个TCP首部及可能有的TCP选项
      3. 服务器必须确认(ACK)客户的SYN,同时自己也得发送一个SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器在单个字节中发送SYN和对客户SYN的ACK(确认)
      4. 客户必须确认服务器的SYN
    2. 常用的TCP选项
      1. MSS选项:发送SYN的TCP异端使用本选项通告对端它的“最大分节大小”(maximum segment size),也就是它在本连接的每个TCP分节中愿意接收的最大数据量。发送端TCP使用接收端的MSS值作为所发送分节的最大大小。 TCP_MAXSEG
      2. 窗口规模选项:原始的TCP连接任何一端能够通告对端的最大窗口大小是65535,因为在TCP首部中相应的字段占16位。随着因特网的发展,要求有更大的窗口以获得尽可能大的吞吐量,这个新选项指定TCP首部中的通告窗口必须扩大(左移0到14位),因此所提供的最大窗口接近1G。在TCP连接上使用窗口规模的前提是它的两个端系统必须都支持这个选项。  SO_RCVBUF
      3. 时间戳选项:用于防止失而复现的分组可能造成的数据损坏。
    3. TCP连接终止(四次挥手,终止一个连接需要4个分节):
      1. 某个应用进程首先调用close,我们称该端执行“主动关闭”(active close)。该端的TCP于是发送一个FIN分节,表示数据发送完毕。(调用close或无论是否自愿地终止进程时,都会导致TCP发送FIN)
      2. 接收到这个FIN的对端执行“被动关闭”(passive close)。这个FIN由TCP确认。它的接收也作为一个文件结束符(EOF)传递给接收端应用进程,因为FIN的接收意味着接收端应用进程在相应连接上再无额外数据可接收。(相当于接收到FIN的同时也接到了一个EOF)
      3. (接第2步,还是在“被动关闭”端)一段时间后,接收到这个文件结束符的应用进程将调用close关闭它的套接字。这导致它的TCP也发送一个FIN
      4. 接收这个最终FIN的原发送端TCP(“主动关闭”端)确认这个FIN
    4. TCP状态转换图:找到一个链接,内有详细的图示。
      1. TIME_WAIT状态:执行主动关闭的一端经历这个状态,该端点停留在这个状态的持续时间是最长分节生命期(maximum segment lifetime,MSL)的两倍,有时候称之为2MSL。任何TCP实现都必须为MSL选择一个值,MSL是任何IP数据报能够在因特网中存活的最长时间。(根据标准,TIME_WAIT状态持续时间在1分钟到4分钟之间),每个数据报含有一个成为跳限(hop limit)的8位字段,最大值为255,具有最大跳限的分组在网络中存在的时间不可能超过MSL秒。TIME_WAIT状态存在的理由是:(1) 可靠地实现TCP全双工连接的终止(以最终的ACK丢失为例,处于TIME_WAIT状态的那一端可能不得不重传ACK); (2) 允许老的重复分节在网络中消逝(防止来自某个连接的老的重复分组在该连接已经终止之后再现)。

    端口号:任何时候,多个进程可能同时使用TCP、UDP和SCTP这三种传输层协议中的任何一种,这3种协议都使用16位整数(0-65535)的端口号,来区分这些进程。

      端口的分类:(端口号分配状况) (1) 众所周知的端口(well-known port):0~1023,由IANA分配和控制。可能的话,相同端口号分配给TCP、UDP和SCTP的同一给定服务。例如,不论TCP还是UDP端口号80都被赋予Web服务器,尽管它目前所有实现都单纯使用TCP。 (2) 已登记的端口(registered port):1024~49151,不受IANA控制,不过由IANA登记并提供他们的使用情况清单,以方便整个群体。可能的话,相同端口号也分配给TCP和UDP的同一给定服务。 (3) 临时端口(ephemeral port):49152~65535,又叫动态或私有端口,IANA不管这些端口。

      Unix有保留端口(reserved port)的概念,指的是小于1024的任何端口,只能赋予特权用户进程的套接字,分配使用这些端口的服务器(例如FTP服务器),必须以超级用户特权启动。(下图一开始绑定的端口是9999,后来绑定的端口是13,显然,普通用户直接运行程序绑定端口的时候,遇到小于1024的端口,会提示没有操作权限)

      

      套接字:标识每个端点的两个值(IP地址和端口号),TCP连接/UDP的套接字对是定义该连接的两个端点的四元组(本地IP、端口,外地IP、端口),在多宿的情形下,同一个关联(SCTP)可能需要多个四元组标识(IP不同,端口一致)

    并发服务器:并发服务器中主服务器循环通过派生一个子进程来处理每个新的连接。

      以port=21为例,使用记号{*:21 , *:*}指出服务器的套接字对。服务器在任意的本地接口的端口21上等待连接请求,外地IP地址和外地端口都没有指定,于是使用*:*来表示,我们称它(整个)为监听套接字。服务器不能指定一个包含多个地址的清单,只能选一个或者所有(* for all),通配(*)地址则把IP地址字段设置为INADDR_ANY(0.0.0.0)。当服务器接收并接受一个客户的连接时,它fork一个自身的副本,让子进程来处理该客户的请求,注意此时产生已连接套接字,特别注意监听套接字和已连接套接字的区别 (将监听套接字填写上实际的IP和端口,例如:监听套接字:{*:21 , *:*}  ->  已连接套接字:{12.106.32.254:21 , 206.168.112.219:1500}) 。如果此时有另一个客户请求连接到同一个服务器,则fork另一个子进程来处理。找到例子一则。

    缓冲区大小及限制(page.45 待续)

  • 相关阅读:
    Fedora install chrome
    Ubuntu13.04 安装 chrome
    cjb
    屏蔽视频广告
    tars环境部署
    rpm包安装失败的解决办法
    Java环境变量配置错误
    Protobuf的安装使用
    fpm打包工具
    gcc6.3的安装
  • 原文地址:https://www.cnblogs.com/tyrus/p/unp_ch2.html
Copyright © 2011-2022 走看看