TCP协议——网络端口号、URG和PSH、定时器

来源:互联网 发布:吃东西知乎 编辑:程序博客网 时间:2024/05/16 23:36

一、TCP协议概念

  TCP(Transmission Control Protocol 传输控制协议)是由IETF的RFC 793定义的一种面向连接的、可靠的、基于字节流的传输层通信协议,它属于传输层,与它与用户数据报协议(UDP)是传输层内的两个重要的传输协议。在因特网协议族(Internet protocol suite)中,TCP层是位于IP层之上,应用层之下的中间层。不同主机的应用层之间经常需要可靠的、像管道一样的连接,但是IP层不提供这样的流机制,而是提供不可靠的包交换
  应用层向TCP层发送用于网间传输的、用8位字节表示的数据流,然后TCP把数据流分区成适当长度的报文段(通常受该计算机连接的网络的数据链路层的最大传输单元( MTU)的限制)。之后TCP把结果包传给IP层,由它来通过网络将包传送给接收端实体的TCP层。TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验

下面就是TCP的段格式

看到上图TCP协议的段格式,我们今天主要讨论以下几个问题。

1、一共有多少个有效的网络端口号?网络端口号的常见分类?我们所熟知的网络服务中的端口号有哪些?2、URG和PSH是什么?它们各自有什么特点?它们之间又有什么联系?3、TCP中常见的定时器有哪些?它们各自有什么样的特点和应用场景?

下面我们就以上三个问题分别展开讨论。

二、网络端口

        从TCP的段格式中我们可以看到网络端口号有16位,那么我们也就可以算出网络端口号的有效个数应该为2的16次方也就是65536个,对于这65536个网络端口号,我们做了以下的分类:

        (1)公认端口(Well Known Ports):从0到1023,它们紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务的协议。例如:80端口实际上总是HTTP通讯。
        (2)注册端口(Registered Ports):从1024到49151。它们松散地绑定于一些服务。也就是说有许多服务绑定于这些端口,这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。
        (3)动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口。但也有例外:SUN的RPC端口从32768开始


        端口号很多都有各自不同的用途,在网络服务中有很多的端口使我们应该了解的,这些常见的网络服务的端口有哪些呢?

        对于Linux操作系统而言,我们可以通过查看/etc/services文件来查看我们常见的网络服务端口号

截取其中部分内容如下:

tcpmux1/tcp# TCP port service multiplexerecho7/tcpecho7/udpdiscard9/tcpsink nulldiscard9/udpsink nullsystat11/tcpusersdaytime13/tcpdaytime13/udpnetstat15/tcpqotd17/tcpquotemsp18/tcp# message send protocolmsp18/udpchargen19/tcpttytst sourcechargen19/udpttytst sourceftp-data20/tcpftp21/tcpfsp21/udpfspdssh22/tcp# SSH Remote Login Protocolssh22/udptelnet23/tcpsmtp25/tcpmailtime37/tcptimservertime37/udptimserverrlp39/udpresource# resource locationnameserver42/tcpname# IEN 116whois43/tcpnicnametacacs49/tcp# Login Host Protocol (TACACS)tacacs49/udpre-mail-ck50/tcp# Remote Mail Checking Protocolre-mail-ck50/udpdomain53/tcp# Domain Name Serverdomain53/udpmtp57/tcp# deprecatedtacacs-ds65/tcp# TACACS-Database Servicetacacs-ds65/udpbootps67/tcp# BOOTP serverbootps67/udpbootpc68/tcp# BOOTP clientbootpc68/udptftp69/udpgopher70/tcp# Internet Gophergopher70/udprje77/tcpnetrjsfinger79/tcphttp80/tcpwww# WorldWideWeb HTTPhttp80/udp# HyperText Transfer Protocollink87/tcpttylinkkerberos88/tcpkerberos5 krb5 kerberos-sec# Kerberos v5kerberos88/udpkerberos5 krb5 kerberos-sec# Kerberos v5supdup95/tcphostnames101/tcphostname# usually from sri-niciso-tsap102/tcptsap# part of ISODEacr-nema104/tcpdicom# Digital Imag. & Comm. 300acr-nema104/udpdicomcsnet-ns105/tcpcso-ns# also used by CSO name servercsnet-ns105/udpcso-nsrtelnet107/tcp# Remote Telnetrtelnet107/udppop2109/tcppostoffice pop-2 # POP version 2pop2109/udppop-2pop3110/tcppop-3# POP version 3pop3110/udppop-3sunrpc111/tcpportmapper# RPC 4.0 portmappersunrpc111/udpportmapperauth113/tcpauthentication tap identsftp115/tcpuucp-path117/tcpnntp119/tcpreadnews untp# USENET News Transfer Protocolntp123/tcpntp123/udp# Network Time Protocolpwdgen129/tcp# PWDGEN servicepwdgen129/udploc-srv135/tcpepmap# Location Serviceloc-srv135/udpepmapnetbios-ns137/tcp# NETBIOS Name Servicenetbios-ns137/udpnetbios-dgm138/tcp# NETBIOS Datagram Servicenetbios-dgm138/udpnetbios-ssn139/tcp# NETBIOS session servicenetbios-ssn139/udpimap2143/tcpimap# Interim Mail Access P 2 and 4imap2143/udpimapsnmp161/tcp# Simple Net Mgmt Protocolsnmp161/udpsnmp-trap162/tcpsnmptrap# Traps for SNMPsnmp-trap162/udpsnmptrapcmip-man163/tcp# ISO mgmt over IP (CMOT)cmip-man163/udpcmip-agent164/tcpcmip-agent164/udpmailq174/tcp# Mailer transport queue for Zmailermailq174/udpxdmcp177/tcp# X Display Mgr. Control Protoxdmcp177/udpnextstep178/tcpNeXTStep NextStep# NeXTStep windownextstep178/udpNeXTStep NextStep#  serverbgp179/tcp# Border Gateway Protocolbgp179/udpprospero191/tcp# Cliff Neuman's Prosperoprospero191/udpirc194/tcp# Internet Relay Chatirc194/udpsmux199/tcp# SNMP Unix Multiplexersmux199/udpat-rtmp201/tcp# AppleTalk routingat-rtmp201/udpat-nbp202/tcp# AppleTalk name bindingat-nbp202/udpat-echo204/tcp# AppleTalk echoat-echo204/udpat-zis206/tcp# AppleTalk zone informationat-zis206/udpqmtp209/tcp# Quick Mail Transfer Protocolqmtp209/udpz3950210/tcpwais# NISO Z39.50 databasez3950210/udpwaisipx213/tcp# IPXipx213/udpimap3220/tcp# Interactive Mail Accessimap3220/udp# Protocol v3pawserv345/tcp# Perf Analysis Workbenchpawserv345/udpzserv346/tcp# Zebra serverzserv346/udpfatserv347/tcp# Fatmen Serverfatserv347/udprpc2portmap369/tcprpc2portmap369/udp# Coda portmappercodaauth2370/tcpcodaauth2370/udp# Coda authentication serverclearcase371/tcpClearcaseclearcase371/udpClearcaseulistserv372/tcp# UNIX Listservulistserv372/udpldap389/tcp# Lightweight Directory Access Protocolldap389/udpimsp406/tcp# Interactive Mail Support Protocolimsp406/udpsvrloc427/tcp# Server Locationsvrloc427/udphttps443/tcp# http protocol over TLS/SSLhttps443/udpsnpp444/tcp# Simple Network Paging Protocolsnpp444/udpmicrosoft-ds445/tcp# Microsoft Naked CIFSmicrosoft-ds445/udpkpasswd464/tcpkpasswd464/udpurd465/tcpssmtp smtps  # URL Rendesvous Directory for SSMsaft487/tcp# Simple Asynchronous File Transfersaft487/udpisakmp500/tcp# IPsec - Internet Security Associationisakmp500/udp#  and Key Management Protocolrtsp554/tcp# Real Time Stream Control Protocolrtsp554/udpnqs607/tcp# Network Queuing systemnqs607/udpnpmp-local610/tcpdqs313_qmaster# npmp-local / DQSnpmp-local610/udpdqs313_qmasternpmp-gui611/tcpdqs313_execd# npmp-gui / DQSnpmp-gui611/udpdqs313_execdhmmp-ind612/tcpdqs313_intercell# HMMP Indication / DQShmmp-ind612/udpdqs313_intercellasf-rmcp623/udp# ASF Remote Management and Control Protocolqmqp628/tcpqmqp628/udpipp631/tcp# Internet Printing Protocolipp631/udp#

三、TCP标志位之URG和PSH

        URG(紧急位):设置为1时,首部中的紧急指针有效;为0时,紧急指针没有意义。

        PSH(推位):当设置为1时,要求把数据尽快的交给应用层,不做处理

        通常的数据中都会带有PSH但URG只在紧急数据的时设置,也称“带外数据”,解释如下:

  紧急数据:URG标志设置为1时,紧急指针才有效,紧急方式是向对方发送紧急数据的一种方式,表示数据要优先处理。他是一个正的偏移量,与TCP收不中序号字段的值相加表示紧急数据后面的字节,即紧急指针是指向紧急数据最后一个字节的下一个字节。这是协议编写上的错误,RFC1122中对此给出了更正说明,紧急指针是数据最后一个字节,不是最后字节的下一位置,TCP首部中只有紧急指针指出紧急数据的位置,他所指的字节为紧急数据,但没有办法指定紧急数据的长度。

  URG=1,表示紧急指针指向包内数据段的某个字节(数据从第一字节到指针所指向字节就是紧急数据)不进入缓冲区(一般不都是待发送的数据要先进入发送缓存吗?就直接交个上层进程,余下的数据都是要进入接收缓冲的;一般来说TCP是要等到整个缓存都填满了后在向上交付,但是如果PSH=1的话,就不用等到整个缓存都填满,直接交付,但是这里的交付仍然是从缓冲区交付的,URG是不要经过缓冲区的

四、TCP的七个定时器

 1.建立连接定时器(connection-establishment timer)

 2.重传定时器(retransmission timer)

 3.延迟应答定时器(delayed ACK timer)

 4.坚持定时器(persist timer)

 5.保活定时器(keepalive timer)

 6.FIN_WAIT_2定时器(FIN_WAIT_2 timer)

 7.TIME_WAIT定时器 (TIME_WAIT timer, 也叫2MSL timer)

下面分别介绍一下这几种定时器:

1.建立连接定时器(connection-establishment timer)

        顾名思义,这个定时器是在建立连接的时候使用的, 我们知道, TCP建立连接需要3次握手, 如下图所示:
这里写图片描述
        建立连接的过程中,在发送SYN时, 会启动一个定时器(默认应该是3秒),如果SYN包丢失了, 那么3秒以后会重新发送SYN包的(当然还会启动一个新的定时器, 设置成6秒超时),当然也不会一直没完没了的发SYN包, 在/proc/sys/net/ipv4/tcp_syn_retries 可以设置到底要重新发送几次SYN包。

2.重传定时器(retransmission timer)

        重传定时器在TCP发送数据时设定,在计时器超时后没有收到返回的确认ACK,发送端就会重新发送队列中需要重传的报文段。使用RTO重传计时器一般有如下规则:

  1. 当TCP发送了位于发送队列最前端的报文段后就启动这个RTO计时器;
  2. 如果队列为空则停止计时器,否则重启计时器;
  3. 当计时器超时后,TCP会重传发送队列最前端的报文段;
  4. 当一个或者多个报文段被累计确认后,这个或者这些报文段会被清除出队列

      重传计时器保证了接收端能够接收到丢失的报文段,继而保证了接收端交付给接收进程的数据始终的有序完整的。因为接收端永远不会把一个失序不完整的报文段交付给接收进程。

3.延迟应答定时器(delayed ACK timer)

      延迟应答也被成为捎带ACK, 这个定时器是在延迟应答的时候使用的。 为什么要延迟应答呢? 延迟应答是为了提高网络传输的效率。

      举例说明,比如服务端收到客户端的数据后, 不是立刻回ACK给客户端, 而是等一段时间(一般最大200ms),这样如果服务端要是有数据需要发给客户端,那么这个ACK就和服务端的数据一起发给客户端了, 这样比立即回给客户端一个ACK节省了一个数据包。

4.坚持定时器(persist timer)

      我们已经知道TCP通过让接收方指明希望从发送方接收的数据字节数(即窗口大小)来进行流量控制。如果窗口大小为 0会发生什么情况呢?这将有效地阻止发送方传送数据,直到窗口变为非0为止。接收端窗口变为非0后,就会发送一个确认ACK指明需要的报文段序号以及窗口大小。

      如果这个确认ACK丢失了,则双方就有可能因为等待对方而使连接终止:接收方等待接收数据(因为它已经向发送方通告了一个非0的窗口),而发送方在等待允许它继续发送数据的窗口更新。为防止这种死锁情况的发生,发送方使用一个坚持定时器 (persist timer)来周期性地向接收方查询,以便发现窗口是否已增大。这些从发送方发出的报文段称为窗口探查 (window probe)。

5.保活定时器(keepalive timer)

      在TCP连接建立的时候指定了SO_KEEPALIVE,保活定时器才会生效。如果客户端和服务端长时间没有数据交互,那么需要保活定时器来判断是否对端还活着,但是这个其实很不实用,因为默认是2小时没有数据交互才探测,时间实在是太长了。如果你真的要确认对端是否活着, 那么应该自己实现心跳包,而不是依赖于这个保活定时器。

6.FIN_WAIT_2定时器(FIN_WAIT_2 timer)

      主动关闭的一端调用完close以后(即发FIN给被动关闭的一端, 并且收到其对FIN的确认ACK)则进入FIN_WAIT_2状态。如果这个时候因为网络突然断掉、被动关闭的一段宕机等原因,导致主动关闭的一端不能收到被动关闭的一端发来的FIN,主动关闭的一段总不能一直傻等着,占着资源不撒手吧?这个时候就需要FIN_WAIT_2定时器出马了, 如果在该定时器超时的时候,还是没收到被动关闭一端发来的FIN,那么不好意思, 不等了, 直接释放这个链接。FIN_WAIT_2定时器的时间可以从/proc/sys/net/ipv4/tcp_fin_timeout中查看和设置。

7.TIME_WAIT定时器 (TIME_WAIT timer, 也叫2MSL timer)

      TIME_WAIT是主动关闭连接的一端最后进入的状态, 而不是直接变成CLOSED的状态, 为什么呢?第一个原因是万一被动关闭的一端在超时时间内没有收到最后一个ACK, 则会重发最后的FIN,2MSL(报文段最大生存时间)等待时间保证了重发的FIN会被主动关闭的一段收到且重新发送最后一个ACK;另外一个原因是在2MSL等待时间时,任何迟到的报文段会被接收并丢弃,防止老的TCP连接的包在新的TCP连接里面出现。不可避免的,在这个2MSL等待时间内,不会建立同样(源IP, 源端口,目的IP,目的端口)的连接。


        
原创粉丝点击