1.什么是零拷貝
零拷貝,不是不需要拷貝,而是盡可能地減少不必要的拷貝,以節省CPU的資源,減少因背景關系切換而造成的資源浪費
背景關系切換:比如用戶在占著CPU,然后此時作業系統要用,那么就要把用戶挪開,把作業系統放上去,也就是把上一個行程的東西挪走,下一個行程的東西挪進來,這就是一次背景關系切換
重點:Linux用到的零拷貝
①傳統的資料傳送
buffer = File.read
Socket.send(buffer)
此時會經過4次拷貝,4次背景關系切換,
先來看四次拷貝

再來看四次背景關系切換

②MMAP記憶體映射
將磁盤上的資料,直接和應用行程緩沖區進行一個映射,省掉了檔案緩沖區這一步
發生了3次拷貝,4次背景關系切換

③Linux2.1里面,提出了sendfile(從這開始就已經提供了零拷貝)
3或者2次拷貝,2次背景關系切換
如果硬體支持,可以是2次拷貝,就是中間的CPU拷貝都不需要了,直接傳檔案讀取緩沖區的起始地址和長度,右邊的DMA拷貝直接拷貝檔案讀取緩沖區的,

④Linux之slice
2次拷貝,2次背景關系切換
PIPE是管道,本質上來講就是兩個緩沖區共用了同一塊物理記憶體,

2.網路傳輸時,直接記憶體比堆記憶體快在哪?
進行網路通信的時候,盡量用直接記憶體,原因?
①每個TCP的Socket的作業系統內核中,都有一個發送緩沖區和一個接識訓沖區,任何語言都是這樣,如圖

應用行程將需要發送的資料發送到套接字發送緩沖區,然后再發送出去
②如果將應用行程緩沖區設定在堆

那么發送資料時,會先將資料發送到直接記憶體中的緩沖區,然后再發送到socket緩沖區,
如果本來就設定在直接記憶體,就避免了第一次拷貝,也就是避免了二次拷貝,
為什么非得先拷貝到直接記憶體呢?
因為堆中有垃圾回識訓制,如果從堆中,直接發送到socket,那么此時如果發生了GC,相應的記憶體地址,就會發生變化,只有發生Full GC的時候,才會順便回收下直接記憶體,所以在直接記憶體中,更有保障
3.TCP拆包/粘包
拆包,就是一分多,粘包,就是多合一
我的理解,拆包就是,不能一次性發送很多資料,需要把整個資料拆分成多個,粘包,就是一次發的資料量太少了,把多個資料量少的包,粘在一起,就是粘包,
如何解決TCP的粘包拆包特性?
①訊息弄成定長的
②或者訊息頭包括訊息的長度
③使用特殊的分隔符(比如ftp協議,對不同的訊息,使用回車換行符,來區分不同的訊息)
4.UDP用在哪
①需要多播的,TCP只能單播
②丟包不影響正常使用的軟體
UDP實作的軟體,不想讓他丟包,怎么辦?
上層應用自己來實作可靠性傳輸,如UDT,據說HTTP3會用UDT來實作
5.DDOS攻擊是啥
DDOS就是利用合理的服務請求,去占用非常多的服務資源,使得正常的用戶無法得到回應,
常見的DDOS有:計算機網路帶寬攻擊和連通性攻擊
前者的意思就是以極大的通信量去沖擊網路,使所有可用的網路資源消耗殆盡,使得合法的用戶的請求無法得到回應
后者的意思是大量的連接請求去沖擊服務器,使得所有可用的資源被消耗殆盡
SYN洪水攻擊就是連通性攻擊,利用了TCP協議的缺陷,發送了大量的半連接請求,耗費資源
6.socket是啥
TCP用主機的IP地址加上主機上的埠號作為TCP連接的端點,這種端點就叫做套接字socket,
作業系統把底層的所有與網路通信相關的細節都隱藏起來了,用socket來進行操作,它是一個門面模式,呼叫connect方法就連接了,內部的細節不用管,
可以理解為它把傳輸層,及以下的協議,全都封裝起來了,從應用層視角往下層看,就是socket
7.一次完整的http請求的程序

http1.0,在客戶端渲染完了之后,就關閉TCP連接了(短連接)
而1.1就有個keep_alive,先保留一會這個連接,類似于長連接
2.0就有個多路復用,服務端推送和請求頭壓縮
DNS劫持,意思就是把DNS決議來的ip地址,換成一個錯誤的ip地址,有可能是釣魚網站的ip地址
HTTP劫持,意思就是劫持http請求報文或者回應報文,解決辦法:用https
8.TCP UDP區別
TCP面向連接,有三次握手和四次揮手,UDP沒有連接,所以也可用于廣播
TCP有可靠性,具體為超時重傳(根據往返時延來計算等多久需要重傳)和應答確認
TCP有資料排序,即在對端,各個組結合的時候,如何根據編號排序
TCP有流量控制(滑動視窗)和擁塞控制
TCP是全雙工,udp應該也是,但是udp偏向單工
洪泛攻擊就是有很多客戶端,客戶端第一次發送的報文,源ip地址是假的,所以服務器發送了確認報文之后,就一直得不到回應,就一直等待,浪費著資源,如SYN洪水攻擊

9.關于TCP的四次揮手
四次揮手全程序(這個圖,四次揮手這里有錯誤,需要把回傳的seq改成ack)

為什么需要四次揮手?
因為TCP是全雙工的,客戶端發送給服務端FIN的時候,說明客戶端不往服務端發資料了,但是服務端可以往客戶端發資料,客戶端還可以接收資料,只有兩邊都單獨發送了FIN的時候,才能確保連接需要斷開了,
注意:四次揮手,在實際情況中,不一定非得是四次,中間兩步,有可能合并
為什么需要TIME_WAINTING狀態?
①處于TIME_WAINTING狀態時,不允許應用立即釋放埠,等TIME_WAINTING的時間,服務器一般會把資料全部傳完,此時再釋放
②如果客戶端發送的分手確認信號,即第四次揮手,丟失了,那么服務端會再次發送,如果不等TIME_WAINTING的時間,那么服務端重新發送的第三次揮手,客戶端就接受不到了
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/354582.html
標籤:其他
上一篇:Chrome開發工具顯示檔案名和行號而不是main.js
下一篇:docker-compsose 搭建minio集群(2021-10月-11月左右的版本)+nginx反向代理及負載均衡(配置超詳細講解)
