下面就是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开始。
截取其中部分内容如下:
tcpmux 1/tcp # TCP port service multiplexer
echo 7/tcp
echo 7/udp
discard 9/tcp sink null
discard 9/udp sink null
systat 11/tcp users
daytime 13/tcp
daytime 13/udp
netstat 15/tcp
qotd 17/tcp quote
msp 18/tcp # message send protocol
msp 18/udp
chargen 19/tcp ttytst source
chargen 19/udp ttytst source
ftp-data 20/tcp
ftp 21/tcp
fsp 21/udp fspd
ssh 22/tcp # SSH Remote Login Protocol
ssh 22/udp
telnet 23/tcp
smtp 25/tcp mail
time 37/tcp timserver
time 37/udp timserver
rlp 39/udp resource # resource location
nameserver 42/tcp name # IEN 116
whois 43/tcp nicname
tacacs 49/tcp # Login Host Protocol (TACACS)
tacacs 49/udp
re-mail-ck 50/tcp # Remote Mail Checking Protocol
re-mail-ck 50/udp
domain 53/tcp # Domain Name Server
domain 53/udp
mtp 57/tcp # deprecated
tacacs-ds 65/tcp # TACACS-Database Service
tacacs-ds 65/udp
bootps 67/tcp # BOOTP server
bootps 67/udp
bootpc 68/tcp # BOOTP client
bootpc 68/udp
tftp 69/udp
gopher 70/tcp # Internet Gopher
gopher 70/udp
rje 77/tcp netrjs
finger 79/tcp
http 80/tcp www # WorldWideWeb HTTP
http 80/udp # HyperText Transfer Protocol
link 87/tcp ttylink
kerberos 88/tcp kerberos5 krb5 kerberos-sec # Kerberos v5
kerberos 88/udp kerberos5 krb5 kerberos-sec # Kerberos v5
supdup 95/tcp
hostnames 101/tcp hostname # usually from sri-nic
iso-tsap 102/tcp tsap # part of ISODE
acr-nema 104/tcp dicom # Digital Imag. & Comm. 300
acr-nema 104/udp dicom
csnet-ns 105/tcp cso-ns # also used by CSO name server
csnet-ns 105/udp cso-ns
rtelnet 107/tcp # Remote Telnet
rtelnet 107/udp
pop2 109/tcp postoffice pop-2 # POP version 2
pop2 109/udp pop-2
pop3 110/tcp pop-3 # POP version 3
pop3 110/udp pop-3
sunrpc 111/tcp portmapper # RPC 4.0 portmapper
sunrpc 111/udp portmapper
auth 113/tcp authentication tap ident
sftp 115/tcp
uucp-path 117/tcp
nntp 119/tcp readnews untp # USENET News Transfer Protocol
ntp 123/tcp
ntp 123/udp # Network Time Protocol
pwdgen 129/tcp # PWDGEN service
pwdgen 129/udp
loc-srv 135/tcp epmap # Location Service
loc-srv 135/udp epmap
netbios-ns 137/tcp # NETBIOS Name Service
netbios-ns 137/udp
netbios-dgm 138/tcp # NETBIOS Datagram Service
netbios-dgm 138/udp
netbios-ssn 139/tcp # NETBIOS session service
netbios-ssn 139/udp
imap2 143/tcp imap # Interim Mail Access P 2 and 4
imap2 143/udp imap
snmp 161/tcp # Simple Net Mgmt Protocol
snmp 161/udp
snmp-trap 162/tcp snmptrap # Traps for SNMP
snmp-trap 162/udp snmptrap
cmip-man 163/tcp # ISO mgmt over IP (CMOT)
cmip-man 163/udp
cmip-agent 164/tcp
cmip-agent 164/udp
mailq 174/tcp # Mailer transport queue for Zmailer
mailq 174/udp
xdmcp 177/tcp # X Display Mgr. Control Proto
xdmcp 177/udp
nextstep 178/tcp NeXTStep NextStep # NeXTStep window
nextstep 178/udp NeXTStep NextStep # server
bgp 179/tcp # Border Gateway Protocol
bgp 179/udp
prospero 191/tcp # Cliff Neuman's Prospero
prospero 191/udp
irc 194/tcp # Internet Relay Chat
irc 194/udp
smux 199/tcp # SNMP Unix Multiplexer
smux 199/udp
at-rtmp 201/tcp # AppleTalk routing
at-rtmp 201/udp
at-nbp 202/tcp # AppleTalk name binding
at-nbp 202/udp
at-echo 204/tcp # AppleTalk echo
at-echo 204/udp
at-zis 206/tcp # AppleTalk zone information
at-zis 206/udp
qmtp 209/tcp # Quick Mail Transfer Protocol
qmtp 209/udp
z3950 210/tcp wais # NISO Z39.50 database
z3950 210/udp wais
ipx 213/tcp # IPX
ipx 213/udp
imap3 220/tcp # Interactive Mail Access
imap3 220/udp # Protocol v3
pawserv 345/tcp # Perf Analysis Workbench
pawserv 345/udp
zserv 346/tcp # Zebra server
zserv 346/udp
fatserv 347/tcp # Fatmen Server
fatserv 347/udp
rpc2portmap 369/tcp
rpc2portmap 369/udp # Coda portmapper
codaauth2 370/tcp
codaauth2 370/udp # Coda authentication server
clearcase 371/tcp Clearcase
clearcase 371/udp Clearcase
ulistserv 372/tcp # UNIX Listserv
ulistserv 372/udp
ldap 389/tcp # Lightweight Directory Access Protocol
ldap 389/udp
imsp 406/tcp # Interactive Mail Support Protocol
imsp 406/udp
svrloc 427/tcp # Server Location
svrloc 427/udp
https 443/tcp # http protocol over TLS/SSL
https 443/udp
snpp 444/tcp # Simple Network Paging Protocol
snpp 444/udp
microsoft-ds 445/tcp # Microsoft Naked CIFS
microsoft-ds 445/udp
kpasswd 464/tcp
kpasswd 464/udp
urd 465/tcp ssmtp smtps # URL Rendesvous Directory for SSM
saft 487/tcp # Simple Asynchronous File Transfer
saft 487/udp
isakmp 500/tcp # IPsec - Internet Security Association
isakmp 500/udp # and Key Management Protocol
rtsp 554/tcp # Real Time Stream Control Protocol
rtsp 554/udp
nqs 607/tcp # Network Queuing system
nqs 607/udp
npmp-local 610/tcp dqs313_qmaster # npmp-local / DQS
npmp-local 610/udp dqs313_qmaster
npmp-gui 611/tcp dqs313_execd # npmp-gui / DQS
npmp-gui 611/udp dqs313_execd
hmmp-ind 612/tcp dqs313_intercell # HMMP Indication / DQS
hmmp-ind 612/udp dqs313_intercell
asf-rmcp 623/udp # ASF Remote Management and Control Protocol
qmqp 628/tcp
qmqp 628/udp
ipp 631/tcp # Internet Printing Protocol
ipp 631/udp
#
URG(紧急位):设置为1时,首部中的紧急指针有效;为0时,紧急指针没有意义。
PSH(推位):当设置为1时,要求把数据尽快的交给应用层,不做处理
通常的数据中都会带有PSH但URG只在紧急数据的时设置,也称“带外数据”,解释如下:
紧急数据:URG标志设置为1时,紧急指针才有效,紧急方式是向对方发送紧急数据的一种方式,表示数据要优先处理。他是一个正的偏移量,与TCP收不中序号字段的值相加表示紧急数据后面的字节,即紧急指针是指向紧急数据最后一个字节的下一个字节。这是协议编写上的错误,RFC1122中对此给出了更正说明,紧急指针是数据最后一个字节,不是最后字节的下一位置,TCP首部中只有紧急指针指出紧急数据的位置,他所指的字节为紧急数据,但没有办法指定紧急数据的长度。
URG=1,表示紧急指针指向包内数据段的某个字节(数据从第一字节到指针所指向字节就是紧急数据)不进入缓冲区(一般不都是待发送的数据要先进入发送缓存吗?就直接交个上层进程,余下的数据都是要进入接收缓冲的;一般来说TCP是要等到整个缓存都填满了后在向上交付,但是如果PSH=1的话,就不用等到整个缓存都填满,直接交付,但是这里的交付仍然是从缓冲区交付的,URG是不要经过缓冲区的
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重传计时器一般有如下规则:
- 当TCP发送了位于发送队列最前端的报文段后就启动这个RTO计时器;
- 如果队列为空则停止计时器,否则重启计时器;
- 当计时器超时后,TCP会重传发送队列最前端的报文段;
- 当一个或者多个报文段被累计确认后,这个或者这些报文段会被清除出队列
重传计时器保证了接收端能够接收到丢失的报文段,继而保证了接收端交付给接收进程的数据始终的有序完整的。因为接收端永远不会把一个失序不完整的报文段交付给接收进程。
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,目的端口)的连接。