欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    關注“腳本之家”,與百萬開發者在一起

    出處:小白debug(ID:)如若轉載請聯系原公眾號直入主題。方兄最近寫了篇很贊的文章寫給想去字節寫 Go 的你,里面提到了兩個問題。連接一個IP 不存在的主機時,握手過程是怎樣的?連接一個IP 地址存在但端口號不存在的主機時,握手過程又是怎樣的呢?讓我回想起曾經也被面試官問過類似的問題,意識到應該很多朋友會對這個問題感興趣。所以來給大家嘮嘮。這兩個問題可以延伸出非常多的點??赐炅?,說不定能加分!正常情況的握手過程是怎么樣的

    上面提到的問題,其實是指TCP的三次握手流程。這絕對是面試八股文里的老股了。

    我們簡單回顧下基礎知識點。

    正常情況下的TCP三次握手

    在服務端啟動好后會調用()方法,進入到狀態,然后靜靜等待客戶端的連接請求到來。

    而此時客戶端主動調用(IP地址),就會向某個IP地址發起第一次握手,發送SYN到目的服務器。

    服務器在收到第一次握手后就會響應客戶端,這是第二次握手。

    客戶端在收到第二次握手的消息后,響應服務的一個ACK,這算第三次握手,此時客戶端 就會進入狀態,認為連接已經建立完成。

    通過抓包可以直觀看出三次握手的流程。

    正常三次握手抓包連一個 IP 不存在的主機時,握手過程是怎樣的

    那不存在的IP,分兩種,局域網內和局域網外的。

    家用路由器局域網互聯

    我以我家里的情況舉例。

    家里有一臺家用路由器。本質上它的功能已經集成了我們常說的路由器主機id找不到,交換機和無線接入點的功能了。

    其中路由器和交換機在之前寫過,已經詳細介紹過了,就不再說一遍了。無線接入點基本可以認為就是個放出 wifi 信號的組件。

    家用路由器下,連著我的N臺設備,包括手機和電腦,他們的IP都有個共同點。都是192.168.31.xx形式的。其中,我的電腦的IP是192.168.31.6,這個可以通過查到。

    電腦主機id怎么查_主機id找不到_怎樣查看pct主機id

    符合這個形式的這些個設備,本質上就是通過各種設備(wifi或交換機等)接入到上圖路由器的e2端口,他們共同構成一個局域網。

    因此主機id找不到,在我家,我們可以粗暴點認為只要是 192.168.31.xx形式的IP,就是局域網內的IP。否則就是局域網外的IP,比如192.0.2.2。

    目的IP在局域網內

    因為通過 可以查到我的局域網內IP是192.168.31.6,這里盲猜末尾+1是不存在的 IP 。試了下,192.168.31.7還真不存在。

    $?ping?192.168.31.7
    PING?192.168.31.7?(192.168.31.7):?56?data?bytes
    Request?timeout?for?icmp_seq?0
    Request?timeout?for?icmp_seq?1
    Request?timeout?for?icmp_seq?2
    Request?timeout?for?icmp_seq?3
    ^C
    ---?192.168.31.7?ping?statistics?---
    5?packets?transmitted,?0?packets?received,?100.0%?packet?loss

    于是寫個程序嘗試連這個IP 。下面的代碼是寫的,大家不看代碼也沒關系,放出來只是方便大家自己復現的時候用的。

    //?tcp客戶端
    package?main

    import?(
    ????"fmt"
    ????"io"
    ????"net"
    ????"os"
    )

    func?main()?{
    ????client,?err?:=?net.Dial("tcp",?"192.168.31.7:8081")
    ????if?err?!=?nil?{
    ????????fmt.Println("err:",?err)
    ????????return
    ????}

    ????defer?client.Close()
    ????go?func()?{
    ????????input?:=?make([]byte,?1024)
    ????????for?{
    ????????????n,?err?:=?os.Stdin.Read(input)
    ????????????if?err?!=?nil?{
    ????????????????fmt.Println("input?err:",?err)
    ????????????????continue
    ????????????}
    ????????????client.Write([]byte(input[:n]))
    ????????}
    ????}()

    ????buf?:=?make([]byte,?1024)
    ????for?{
    ????????n,?err?:=?client.Read(buf)
    ????????if?err?!=?nil?{
    ????????????if?err?==?io.EOF?{
    ????????????????return
    ????????????}
    ????????????fmt.Println("read?err:",?err)
    ????????????continue
    ????????}
    ????????fmt.Println(string(buf[:n]))
    ????}
    }

    然后嘗試抓包。

    連一個不存在的IP(局域網內)抓包

    可以發現根本沒有三次握手的包,只有一些 ARP 包,在詢問“誰是192.168.31.7,告訴一下192.168.31.6” 。

    這里有三個問題

    首先我們看下正常情況下執行,也就是第一次握手 的流程。

    正常的流程

    應用層執行過后,會通過層,操作系統接口,進程會從用戶態進入到內核態,此時進入傳輸層,因為是TCP第一次握手,會加入TCP頭,且置SYN標志。

    tcp報頭的SYN

    然后進入網絡層,我想要連的是192.168.31.7,雖然它是我瞎編的,但IP頭還是得老老實實把它加進去。

    此時需要重點介紹的是鄰居子系統,它在網絡層和數據鏈路層之間??梢酝ㄟ^ARP協議將目的IP轉為對應的MAC地址,然后數據鏈路層就可以用這個MAC地址組裝幀頭。

    我們看下那么ARP協議的流程是

    怎樣查看pct主機id_電腦主機id怎么查_主機id找不到

    ARP流程

    1.先到本地ARP表查一下有沒有192.168.31.7對應的mac地址,有的話就返回,這里顯然是不可能會有的。

    可以通過 arp -a 命令查看本機的 arp表都記錄了哪些信息

    $?arp?-a
    ??(192.168.31.1)?at?88:c1:97:59:d1:c3?on?en0?ifscope?[ethernet]
    ??(224.0.0.251)?at?1:0:4e:0:1:fb?on?en0?ifscope?permanent?[ethernet]
    ??(239.255.255.250)?at?1:0:3e:7f:ff:fb?on?en0?ifscope?permanent?[ethernet]

    2.看下192.168.31.7跟本機IP 192.168.31.6在不在一個局域網下。如果在的話,就在局域網內發一個 arp 廣播,內容就是 前面提到的 “誰是192.168.31.7,告訴一下192.168.31.6”。

    3.如果目的IP跟本機IP不在同一個局域網下,那么會去獲取默認網關的MAC地址,這里就是指獲取家用路由器的MAC地址。然后把消息發給家用路由器,讓路由器發到互聯網,找到下一跳路由器,一跳一跳的發送數據,直到把消息發到目的IP上,又或者找不到目的地最終被丟棄。

    4.第2和第3點都是本地沒有查到 ARP 緩存記錄的情況,這時候會把SYN報文放進一個隊列(叫)里暫存起來,然后發起ARP請求;等ARP層收到ARP回應報文之后,會再從緩存中取出 SYN 報文,組裝 MAC 幀頭,完成剛剛沒完成的發送流程。

    如果經過 ARP 流程能正常返回 MAC 地址,那皆大歡喜,直接給數據鏈路層,經過ring 后傳到網卡,發出去。

    但因為現在這個IP是瞎編的,因此不可能得到目的地址 MAC ,所以消息也一直沒法到數據鏈路層。整個流程卡在了ARP流程中。

    而抓包是在數據鏈路層之后進行的,因此 TCP 第一次握手的包一直沒能抓到,只能抓到為了獲得 192.168.31.7的MAC地址的ARP請求。

    發送數據時,是在經過數據鏈路層之后的 方法執行抓包操作的,這是屬于網卡驅動層的方法了。

    順帶一提,接收端抓包是在 core 方法里執行的,也屬于網卡驅動層。感興趣的朋友們可以以這個為關鍵詞搜索相關知識點哈

    此時 因為 TCP 協議是可靠的協議,對于 TCP 層來說,第一次握手的消息,已經發出去了,但是一直沒有收到 ACK。也不知道消息是出去后是遇到什么事了。為了保證可靠性,它會不斷重發。而每一次重發,都會因為同樣的原因(沒有目的 MAC 地址)而尬在了 ARP 那個流程里。因此,才看到好幾次重復的 ARP 消息。那回到剛剛的三個問題小結

    連一個 IP 不存在的主機時,如果目的IP在局域網內,則第一次握手會失敗,接著不斷嘗試重發握手的請求。同時,本機會不斷發出ARP請求,企圖獲得目的機器的 MAC 地址。并且,因為沒能獲得目的 MAC 地址,這些 TCP 握手請求最終都發不出去,

    目的IP在局域網外

    上面提到的是,目的 IP 在局域網內的情況,下面討論目的IP在局域網外的情況。

    瞎編一個不是 192.168.31.xx形式的 IP 作為這次要用的局域網外IP, 比如10.225.31.11。

    先抓包看一下。

    連一個不存在的IP(局域網外)抓包

    怎樣查看pct主機id_主機id找不到_電腦主機id怎么查

    這次的現象是能發出 TCP 第一次握手的SYN包。

    這里有兩個問題

    為什么連局域網外的IP現象跟連局域網內不一致?

    這個問題的答案其實在上面ARP 的流程里已經提到過了,如果目的 IP 跟本機 IP 不在同一個局域網下,那么會去獲取默認網關的 MAC 地址,這里就是指獲取家用路由器的MAC地址。

    此時ARP流程成功返回家用路由器的 MAC 地址,數據鏈路層加入幀頭,消息通過網卡發到了家用路由器上。

    消息會通過互聯網一直傳遞到某個局域網為 10.225.31.xx的路由器上,那個路由器 發出ARP 請求,詢問他們局域網內的機器有沒有叫10.225.31.11的 (結果當然沒有)。

    最終沒能發送成功,發送端也就遲遲收不到目的機的第二次握手響應。

    因此觸發TCP重傳。

    TCP第一次握手的重試規律好像不太對?

    在 Linux 中,第一次握手的SYN重傳次數,是通過參數控制的??梢酝ㄟ^下面的方式查看

    $cat?/proc/sys/net/ipv4/tcp_syn_retries
    6

    這里的含義是指syn重傳會發生6次。

    而每次重試都會間隔一定的時間,這里的間隔一般是 1s,2s,4s,8s, 16s, 32s .

    SYN重傳

    而事實上,看我的截圖,是先重試4次,每次都是1s,之后才是 1s,2s,4s,8s, 16s, 32s 的重試。

    這跟我們知道的不太一樣。

    這個是因為我用的是macOS抓的包,跟linux就不是一個系統,各自的TCP協議棧在sync重傳方面的實現都可能會有一定的差異。

    我還聽說oppo和vivo的 syn重傳 是0.5s起步的。而的 syn重傳 還有自己的專利。

    這些冷知識大家可以不用在意。面試的時候知道linux的就夠了,剩下的可以用來裝逼。畢竟面試官不在意"茴"字到底有幾種寫法。

    連IP 地址存在但端口號不存在的主機的握手過程

    怎樣查看pct主機id_電腦主機id怎么查_主機id找不到

    前面提到的是IP地址壓根就不存在的情況。假如IP地址存在但端口號是瞎編的呢?

    目的IP是回環地址

    連回環地址,端口不存在抓包

    現象也比較簡單,已經IP地址是存在的,也就是在互聯網中這個機器是存在的。

    那么我們可以正常發消息到目的IP,因為對應的MAC地址和IP都是正確的,所以,數據從數據鏈路層到網絡層都很OK。

    直到傳輸層,TCP協議在識別到這個端口號對應的進程根本不存在時,就會把數據丟棄,響應一個RST消息給發送端。

    連回環地址時端口不存在RST是什么?

    我們都是到TCP正常情況下斷開連接是用四次揮手,那是正常時候的優雅做法。

    但異常情況下,收發雙方都不一定正常,連揮手這件事本身都可能做不到,所以就需要一個機制去強行關閉連接。

    RST就是用于這種情況,一般用來異常地關閉一個連接。它在TCP包頭中,在收到置了這個標志位的數據包后,連接就會被關閉,此時接收到 RST的一方,一般會看到一個 reset或 的報錯。

    TCP報頭RST位目的IP在局域網內

    剛剛提到我的本機IP是192.168.31.6,局域網內有臺192.168.31.1。同樣嘗試連一個不存在的端口。

    連存在的局域網內IP,端口不存在抓包

    此時現象跟前者一致。

    唯一不同的是,前者是回環地址,RST數據是從本機的傳輸層返回的。而這次的情況,RST數據是從目的機器的傳輸層返回的。

    連外網地址時端口不存在目的IP在局域網外

    主機id找不到_怎樣查看pct主機id_電腦主機id怎么查

    找一個存在的外網ip,這里我拿了最近剛白嫖的阿里云服務器地址47.102.221.141。(炫耀)

    進行連接連接,發現與前面兩種情況是一致的,目的機器在收到我的請求后,立馬就通過RST標志位斷開了這次的連接。

    連存在的局域網外IP,端口不存在抓包

    這一點跟前面兩種情況一致。

    熟悉小白的朋友們都知道,每次搞事情做測試,都會用 。

    這次也不例外,ping 一下,獲得它的IP: 220.181.38.148。

    $?ping?baidu.com
    PING?baidu.com?(220.181.38.148):?56?data?bytes
    64?bytes?from?220.181.38.148:?icmp_seq=0?ttl=48?time=35.728?ms
    64?bytes?from?220.181.38.148:?icmp_seq=1?ttl=48?time=38.052?ms
    64?bytes?from?220.181.38.148:?icmp_seq=2?ttl=48?time=37.845?ms
    64?bytes?from?220.181.38.148:?icmp_seq=3?ttl=48?time=37.210?ms
    64?bytes?from?220.181.38.148:?icmp_seq=4?ttl=48?time=38.402?ms
    64?bytes?from?220.181.38.148:?icmp_seq=5?ttl=48?time=37.692?ms
    ^C
    ---?baidu.com?ping?statistics?---
    6?packets?transmitted,?6?packets?received,?0.0%?packet?loss
    round-trip?min/avg/max/stddev?=?35.728/37.488/38.402/0.866?ms

    發消息到給百度域名背后的 IP,且瞎隨機指定一個端口8080, 抓包。

    連baidu,端口不存在抓包

    現象卻不一致。沒有RST。而且觸發了第一次握手的重試消息。這是為什么?

    這是因為baidu的機器,作為線上生產的機器,會設置一系列安全策略,比如只對外暴露某些端口,除此之外的端口,都一律拒絕。

    所以很多發到 8080端口的消息都在防火墻這一層就被拒絕掉了,根本到不了目的主機里,而RST是在目的主機的TCP/IP協議棧里發出的,都還沒到這一層,就更不可能發RST了。因此發送端發現消息沒有回應(因為被防火墻丟了),就會重傳。所以才會出現上述抓包里的現象。

    防火墻安全策略總結

    連一個 IP 不存在的主機時

    連IP 地址存在但端口號不存在的主機時

    最后留個問題,連一個不存在的局域網外IP的主機時,我們可以看到TCP的重發規律是:開始時,每隔1s重發五次TCP SYN消息,接著2s,4s,8s,16s,32s都重發一次;

    對比連一個不存在的局域網內IP的主機時,卻是每隔1s重發了4次ARP請求,接著過了32s后才再發出一次ARP請求。已知ARP請求是沒有重傳機制的,它的重試就是TCP重試觸發的,但兩者規律不一致,是為什么?

    圍觀!不限速的阿里云盤新功能來了!

網站首頁   |    關于我們   |    公司新聞   |    產品方案   |    用戶案例   |    售后服務   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權所有