zoukankan      html  css  js  c++  java
  • TCP学习笔记

    TCP协议与其它协议之间的关系:

           +------+ +-----+ +-----+       +-----+                    
           |Telnet| | FTP | |Voice|  ...  |     |  Application Level 
           +------+ +-----+ +-----+       +-----+                    
                 |   |         |             |                       
                +-----+     +-----+       +-----+                    
                | TCP |     | RTP |  ...  |     |  Host Level        
                +-----+     +-----+       +-----+                    
                   |           |             |                       
                +-------------------------------+                    
                |    Internet Protocol & ICMP   |  Gateway Level     
                +-------------------------------+                    
                               |                                     
                  +---------------------------+                      
                  |   Local Network Protocol  |    Network Level     
                  +---------------------------+   

    TCP的流控制是通过在接收者发往发送者的ACK中TCP首部的window字段(接收窗口长度)来实现的:

        TCP provides a means for the receiver to govern the amount of data
        sent by the sender.  This is achieved by returning a "window" with
        every ACK indicating a range of acceptable sequence numbers beyond
        the last segment successfully received.  The window indicates an
        allowed number of octets that the sender may transmit before
        receiving further permission.

    TCP具有超时重发的机制,如果在指定时间内没有接收到相应的ACK,那么相应的Segment将会重新发送。

    可以同时打开多个SOCKET去监听同一个PORT, 那么TCP将首先匹配到指定外部SOCKET地址的TCB,然后再去匹配不指定外部SOCKET地址的TCB。

    icmp可以用于获取另一台机器的时间,发送端在“发送时间戳”字段填入发送的时间,而接收端需要在“接收时间戳”字段写入接收到的时间并再次发回给发送端,这样子一来发送端就可以计算出从往返延迟了。另外RFC1307还描述了一种毫秒级的时间同步协议。

    一个连接同时使用sourceIP destIP sourcePort destPort来唯一确定 。

    为什么TCP需要3次握手而不是2次:

    第一次在面试题里面看到这个问题,根RFC793上的说法,TCP其于IP(Internet Protocol)协议,IP协议是不可靠的,建立一个100%可靠的连接显然不可能。当然,如果连接足够可靠,那我们无须进行这个过程,或者我们可以将握手的次数增加到4次或者5次以得到一个更加稳定的连接),3次连接则是这样子的一个折中。可以避免大部分错误的情况,同时节省建立连接的消耗。

    从另一个方面来说,让连接双方都相互“知道”彼此的ISN,那么至少进行3次握手,两次学习到其中一方的ISN。

    因为握手过程中发送的SYN和ACK可能会迟到或者丢失,所以,在不稳定的网络环境中,两次握手是不恰当的,比如下面的过程,TCP发出ACK之后马上进入ESTABLISHED状态,并通知上层的应用程序,但步骤2中的ACK很可能会丢失。如果某个时候网络环境很糟糕,上层的应用则得到大量无效的连接,这是不恰当的。

        TCP A                                                 TCP B
        CLOSED                                                LISTEN
    1: (SYN_SENT)        ---(SEQ=100,CTL=SYN) -->             (SYN_RECEIVED)
    2: (ESTABLISHED)     <--(SEQ=300,ACK=101,CTL=ACK) --      (ESTABLISHED)
    POSSIBILITY 1


    TCP A TCP B
    CLOSED LISTEN
    1: (SYN_SENT) ---(SEQ=100,CTL=SYN) ... LISTEN
    2: (SYN_SENT) ---(SEQ=110,CTL=SYN) ... LISTEN
    3: ---(SEQ=100,CTL=SYN) --> (SYC_RECEIVED)
    4: (ESTABLISHED) <--(SEQ=200,ACK=101,CTL=ACK) --- (ESTABLISHED)
    5: ---(SEQ=110,CTL=SYN) --> (???)
    POSSIBILITY 2

    一些控制packet的segment length==1

    Usually, TCP packets with a len of 1 are control packets (ACK,SYN,FIN,RST)

    TCP连接断开的过程也比较麻烦,有四次握手的说法,但这种说法可以说不是很准确。

    TCP A
    CLOSE_WAIT_1 ---(SEQ=300,ACK=100,CTL=<FIN,ACK>) --> FIN_WAIT
    CLOSE_WAIT_2 <--(SEQ=100,ACK=301,CTL=<ACK>) --- FIN_WAIT
    TIME_WAIT <--(SEQ=xxx,ACK=301,CTL=<FIN,ACK>) --- LAST_ACK(Close)
    TIME_WAIT ---(SEQ=301,ACK=101,CTL=<ACK>) --> CLOSED
    2MSL(TIME_WAIT)
    CLOSED

    发送方接收到ACK时,在重发队列中所有的SEGMENT,如果SEG.SEQ + SEG.LEN <= ACK.SEQ,则这个SEGMENT被接收者确认(Acknowledged),并可以从队列中移出。

     今天同事做技术交流的时候带回来了一些问题:

    1、三次握手完成之前是否需要accept操作,从上面的握手过程可以知道,只有三次握手完成之后,网络栈才会认为这个东西是正确的。然后才会交给应用进程去处理。

    2、主进程和子进程之间共享socket文件描述符时候,比如nginx,三次握手的时候(中间过程),netstat的时候,这个连接是的进程号是谁的?其实这个现象是不确定的,比如centos平台上面,netstat的时候,进程号部分为-,即不知道这个连接归那个进程号所有。

    3、linux平台上面只要拿到文件描述符就可以对socket进行accept,比如nginx的二进制文件升级的时候,用的就是这个特性。

    其实这些东西都还是些linux 编程的东西,还是回去好好搞LINUX内核和LINUX平台上的编程?FUCK

  • 相关阅读:
    PAT:1006(换个格式输出整数想&#183;)
    PAT 1008(数组循环右移问题)
    kaliLinux 工具dmitry参数解析
    PAT 1004(成绩排名)(C++)
    PAT乙级:我要通过(1003)
    PAT乙级:写出这个数(1002)
    PAT乙级:(3n+1)猜想 (1001)
    Linux初体验
    C语言基础入门:起源
    Linux_ pipe 匿名管道 浅解
  • 原文地址:https://www.cnblogs.com/mosmith/p/6506763.html
Copyright © 2011-2022 走看看