(1)滑動窗口:TCP中採用滑動窗口來進行傳輸控制,滑動窗口的大小意味着接收方還有多大的緩衝區能夠用於接收數據html
滑動窗口存在於數據鏈路層(針對於幀的傳送)和傳輸層(針對字節數據的傳送),二者有不一樣的協議,但基本原理是相近的。linux
滑動窗口指出接收緩衝區中的可用空間,從而確保發送方發送的數據不會溢出緩衝區。算法
窗口時刻動態變化:當接收發送發數據時,窗口大小減少;當接收方從緩衝區中讀取數據時,窗口大小增大。編程
TCP的接收緩衝區滿,它必須等待應用程序從這個緩衝區讀取數據後才能再接收發送方傳來的數據。segmentfault
UDP不提供流控制,按發送方的速率發送數據,無論接收方的緩衝區是否裝得下。數組
## 參考文獻:《UNIX網絡編程》瀏覽器
(2)TCP擁塞的緣由:在早期的時候,通訊的雙方不知道網絡的情況,因此過程當中可能會出現中間節點阻塞丟包,因此就有了滑動窗口機制來解決這個問題。緩存
(3)滑動窗口協議:用於網絡數據傳輸時的流量控制,以免擁塞的發生。若是過多的發送方同時以很快的速度發送大量的數據包,接收方有可能並無那麼高的接收數據能力,所以極易致使網絡的擁塞(併發服務器)。安全
協議中規定,對於窗口內未經確認的分組(傳輸中接收方必須確認收到的數據包。)須要重傳。這種分組的數量最多能夠等於發送窗口的大小。服務器
(4)滑動窗口的值:網絡中沒有出現擁塞,滑動窗口的值能夠增大一些(以便把更多的數據包發送出去);網絡出現擁塞,滑動窗口的值應該減少一些(以減小注入到網絡中的數據包數)
(5)擁塞控制算法:
## 參考文章:淺談TCP擁塞控制算法
#include <sys/types.h>
#include <sys/socket.h>
ssize_t recv(int sockfd, void *buf, size_t len, int flags);- flags:
+ 0:默認設置,此時recv是阻塞接收的,0是常設置的值。
+ MSG_DONTWAIT:非阻塞接收
+ MSG_OOB:接收的是帶外數據
+ ...:其它選項
(1)阻塞IO:使用recv的默認參數一直等數據直到拷貝到用戶空間,這段時間內進程始終阻塞。
A從宿舍(用戶空間)拿着水瓶去飲水機處(內核空間)打水,等到水打滿了以後就離開了。若飲水機沒有水則一直阻塞等待杯子裝滿水爲止,才離開去作別的事情。(這種IO模型是阻塞+同步的)
(2)非阻塞IO:
改變flags,recv無論有沒有獲取到數據都返回(若是沒有數據那麼一段時間後再調用recv看看,如此循環)
B也從宿舍(用戶空間)拿着水瓶去飲水機處(內核空間)打水,打開水龍頭髮現沒有水以後離開了(回到用戶空間)。
只有是檢查無數據的時候是非阻塞的,在數據到達的時候依然要等待複製數據到用戶空間(等着水將水杯裝滿)(這種IO模型是非阻塞+同步的)
(3)同步IO:IO多路複用(select, poll, epoll模型),監聽多個IO對象,對象有變化(有數據)的時候就通知用戶進程(單個進程能夠處理多個socket)
select/epoll的優點並非對於單個鏈接能處理得更快,而是在於能處理更多的鏈接。
(4)異步IO:當進程發起IO 操做以後,就直接返回不再理睬了,直到kernel發送一個信號,告訴進程說IO完成。在這整個過程當中,進程徹底沒有被block。
## 參考文章:簡述同步IO、異步IO、阻塞IO、非阻塞IO之間的聯繫與區別 (以爲他寫的例子特別好,拿來分享)
(1)全雙工:通訊容許數據在兩個方向上同時傳輸,它在能力上至關於兩個單工通訊方式的結合。能夠同時進行信號的雙向傳輸,A→B和B→A,是瞬時同步的。
(2)TCP鏈接:要客戶端->服務器和服務器->客戶端都要創建鏈接
(3)由於TCP的鏈接是全雙工的,應用程序在任什麼時候刻既能夠發送數據也能夠接收數據。TCP
爲了實現可靠數據傳輸, TCP 協議的通訊雙方都必須維護一個序列號, 以標識發送出去的數據包中, 哪些是已經被對方收到的。
三次握手的過程便是通訊雙方相互告知序列號起始值, 並確認對方已經收到了序列號起始值的必經步驟
若是隻是兩次握手, 至多隻有鏈接發起方的起始序列號能被確認, 另外一方選擇的序列號則得不到確認
## 參考文章:https://blog.csdn.net/lengxiao1993/article/details/82771768
(1)三次握手同上
TCP服務器通知高層的應用進程,客戶端向服務器的方向就釋放了,這時候處於半關閉狀態,即客戶端已經沒有數據要發送了,可是服務器若發送數據,客戶端依然要接受。這個狀態還要持續一段時間,也就是整個CLOSE-WAIT狀態持續的時間。
客戶端->服務器:seq=u;服務器收到誰的FIN,發送ack=u+1;
服務器->客戶端:seq=v / seq = w;客戶端收到誰的FIN,發送ack=w+1,再發送本身的序列號seq=u+1
CLOSE-WAIT:當被動關閉方接收到主動關閉方發出的FIN包,被動關閉方發出確認ACK包以後,進入CLOSE-WAIT狀態,處於半關閉狀態,此時主動關閉方沒有數據要發送了,可是被動關閉方可能還有數據須要發送,主動關閉方必須接收它的數據。
TIME-WAIT:主動關閉方接收到被動關閉方發出的FIN包,向被動關閉方發出確認ACK包以後,進入TIME-WAIT狀態。因爲主動關閉方要等待被動關閉方接收到ACK包,報文最長的壽命時間爲2MSL,若是在2MSL內被動關閉方沒有接收到ACK包,會再次重發FIN包,這是一個等待機制。在通過2MSL事件後,主動關閉方纔撤銷TCB,進入CLOSE狀態。
【報文最長的壽命時間:2MSL】
TCP:傳輸控制協議
UDP:用戶數據報協議
TCP應用場景:
UDP應用場景:
- 數據包總量比較少的通訊,好比DNS、SNMP。
- 視頻、音頻等對實時性要求比較高的多媒體通訊。
- 廣播通訊、多播通訊。
## 參考文章: http://www.javashuo.com/article/p-kbkappoe-hc.html
【吞吐量:單位時間內成功地傳送數據的數量】
一、粘包:
應用程序所看到的數據是一個總體,或說是一個流,一條消息有多少字節對應用程序是不可見的【TCP協議是面向流的協議】,這也是容易出現粘包問題的緣由。
UDP是面向消息的協議,每一個UDP段都是一條消息,應用程序必須以消息爲單位提取數據,不能一次提取任意字節的數據
二、怎樣定義消息:
能夠認爲一次性write/send的數據爲一個消息【不管底層怎樣分段分片,TCP協議層會把構成整條消息的數據段排序完成後才呈如今內核緩衝區。】
三、出現粘包的緣由:
由於接收方不知道消息之間的界限,不知道一次性提取多少字節的數據所形成的。
1)客戶端發:消息A,消息B ==> 消息A,消息B
2)客戶端發:消息A,消息B ==> 消息A,消息A+B (消息A太大了 || 服務器不及時接收緩衝區的包,服務端下次再收的時候仍是從緩衝區拿上次遺留的數據)
3)客戶端發:消息A,消息B ==> 消息A+B,消息B (消息A過小了,TCP爲了提升傳輸效率,等緩衝區滿才發送出去)
4)客戶端發:消息A,消息B ==> 消息A+B(消息A和B都過小了,TCP爲了提升傳輸效率,將消息A和B粘包一塊兒發送)
四、粘包的解決方法:
接收端不知道發送端將要傳送的字節流的長度,因此解決粘包的方法就是圍繞,如何讓發送端在發送數據前,把本身將要發送的字節流總大小讓接收端知曉,而後接收端來一個死循環接收完全部數據
1)在兩次send之間調用usleep休眠小一段時間來解決【缺點:傳輸效率大大下降,並且也並不可靠】
2)對數據包進行封包和解包:發送消息的時候,給每一個數據包添加包首部,首部中應該至少包含數據包的長度,這樣接收端在接收到數據後,經過讀取包首部的長度字段,便知道每個數據包的實際長度了。【缺點:會放大網絡延遲帶來的性能損耗】
3)發送端將每一個數據包封裝爲固定長度(不夠的能夠經過補0填充),這樣接收端每次從接收緩衝區中讀取固定長度的數據就天然而然的把每一個數據包拆分開來。
4)在數據包之間設置邊界,如添加特殊符號,這樣,接收端經過這個邊界就能夠將不一樣的數據包拆分開。
因爲主動關閉方要等待被動關閉方接收到ACK包,報文最長的壽命時間爲2MSL,若是在2MSL內被動關閉方沒有接收到ACK包,會再次重發FIN包,這是一個等待機制。
在通過2MSL事件後,主動關閉方纔撤銷TCB,進入CLOSE狀態。
系統用一個4四元組來惟一標識一個TCP鏈接:{local ip, local port,remote ip,remote port}
客戶端(理論值):client發起TCP請求時會綁定一個端口,該端口是獨佔的,不能和其餘TCP鏈接共享
端口的數據結構是unsigned short,端口0不能使用,因此216-1=65535 = TCP理論最大鏈接數
服務器端(理論值):最大TCP鏈接 = 客戶端IP數×客戶端PORT數 ≈ 232(ip最大值) × 216(port最大值) ≈ 248
實際值:對server端,經過增長內存、修改最大文件描述符個數等參數,單機最大併發TCP鏈接數超過10萬是沒問題的
## 參考文章 :http://www.javashuo.com/article/p-umwlekfk-eb.html
建立套接字【socket】,綁定端口【bind】,準備監聽【listen(套接字,等待鏈接隊列的最長長度)】
網絡:兩主機要通訊傳送數據時,就要把應用數據封裝成IP包,而後再交給下一層數據鏈路層繼續封裝成幀;以後根據MAC地址才能把數據從一臺主機,準確無誤的傳送到另外一臺主機。
ARP解析:數據鏈路層,經過IP尋找對方的MAC地址
IP尋址:網絡層,根據目的IP地址,找到目的網絡
完成了TCP的全雙工通訊鏈接,打通了服務器到客戶端的通訊通道
一、TCP鏈接以後就能夠進行通訊了,客戶端到服務器端的通訊,服務器端到客戶端的通訊。
二、鏈接以後網線斷了:select,epoll監測不到斷開或錯誤事件,對於服務端來講會一直維持着這個鏈接。
若是網線斷開的時間短暫,在SO_KEEPALIVE設定的探測時間間隔內,而且兩端在此期間沒有任何針對此長鏈接的網絡操做。當連上網線後此TCP鏈接能夠自動恢復,繼續進行正常的網絡操做。
若是網線斷開的時間很長,超出了SO_KEEPALIVE設定的探測時間間隔,或者兩端期間在此有了任何針對此長鏈接的網絡操做。當連上網線時就會出現ETIMEDOUT或者ECONNRESET的錯誤。你必須從新創建一個新的長鏈接進行網絡操做。
【 服務器要想知道客戶端的意外掉線,須要作心跳包:在客戶端和服務器間定時通知對方本身狀態的一個本身定義的命令字,按照必定的時間間隔發送。
心跳包:定時發送的一個自定義結構體(心跳包或心跳幀),讓對方知道本身「在線」。 以確保連接的有效性。
TCP中已經爲實現了一個叫作心跳的機制,若是設置了心跳,那TCP就會在必定的時間內發送你設置的次數的心跳,而且此信息不會影響你本身定義的協議。
】
三、鏈接以後出現服務器意外掉線之類的錯誤:例如Qt中監聽錯誤信號QAbstractSocket::error(QAbstractSocket::SocketError socketError),當鏈接不上服務器的時候,會發送QAbstractSocket::ConnectionRefusedError錯誤信號,能夠進行響應的處理
發送端在發送數據包以後就開啓一個計時器,在必定時間內沒有收到對方的ACK報文,則從新發送數據,直到發送成功。
影響超時重傳機制協議效率的一個關鍵參數是重傳超時時間(RTO)。
RTO的值被設置過大太小都會對協議形成不利影響。
鏈接往返時間(RTT),指發送端從發送TCP包開始到接收它的當即響應所消耗的時間。
一、建立socket:int socket(int domain/*IPv4*/, int type/*子協議*/, int protocol/*協議號,通常爲0*/);
二、綁定IP和端口號bind:int bind(int sockfd/*套接字*/, const struct sockaddr *addr/*服務器端結構體*/, socklen_t addrlen/*結構體長度*/);
出現沒法綁定setsockopt:setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&opt/*1*/,sizoef(opt));
三、作監聽準備listen:int listen(int sockfd/*套接字*/, int backlog/*等待隊列的容量*/);
四、被動監聽客戶端的鏈接請求並響應accept:int accept(int sockfd/*套接字*/, struct sockaddr *addr/*客戶端結構體*/, socklen_t *addrlen/*結構體長度*/);
五、發送數據send:ssize_t send(int sockfd/*套接字*/, const void *buf/*緩存發送的消息*/, size_t len/*緩存大小*/, int flags/*是否阻塞*/);
六、接收數據recv:ssize_t recv(int sockfd/*套接字*/, void *buf/*緩存接收的消息*/, size_t len/*緩存大小*/, int flags/*是否阻塞*/);
七、關閉TCP鏈接:shutdown:int shutdown(int sockfd, int how/*如何斷開鏈接*/); /*鏈接就會被當即斷開*/
close :int close(int sockfd); /*一次性關掉讀寫,沒法解決多個文件描述符指向了同一個鏈接時的關閉*/
在TCP三次握手的第三步中,若是服務器沒有收到客戶端的最終ACK確認報文,會一直處於SYN_RECV狀態,將客戶端IP加入等待列表,並重發第二步的SYN+ACK報文。重發通常進行3-5次,大約間隔30秒左右輪詢一次等待列表重試全部客戶端。另外一方面,服務器在本身發出了SYN+ACK報文後,會
預分配資源爲即將創建的TCP鏈接儲存信息作準備,這個資源在等待重試期間一直保留。更爲重要的是,服務器資源有限,能夠維護的SYN_RECV狀態超過極限後就再也不接受新的SYN報文,也就是拒絕新的TCP鏈接創建。
一、DOS攻擊:拒絕服務攻擊,【服務資源包括網絡帶寬,文件系統空間容量,開放的進程或者容許的鏈接。這種攻擊會致使資源的匱乏,不管計算機的處理速度多快、內存容量多大、網絡帶寬的速度多快都沒法避免這種攻擊帶來的後果,使計算機或網絡沒法提供正常的服務】
最多見的DoS攻擊有計算機網絡寬帶攻擊和連通性攻擊
二、DDOS攻擊:分佈式拒絕服務攻擊
指藉助於客戶/服務器技術,將多個計算機聯合起來做爲攻擊平臺,對一個或多個目標發動DDOS攻擊,從而成倍地提升拒絕服務攻擊的威力。
面向鏈接、可靠的字節流傳輸
以老師給學生回答作例子:
(1)循環服務器模型:服務器再同一時刻只能響應一個客戶端的請求
例子:當一個學生來上課,老師一直跟着這名學生,直到它解決問題離開教室,老師才能一直解決下一個學生的問題。
只要有學生進入教室,不管這名學生有沒有問題,老師都不能幫助其餘同窗解決問題,須要等到這名學生離開教室爲止
⭐優勢:簡單易懂,沒有同步、加鎖等複雜狀況,也沒有進程建立等開銷
由於UDP是短鏈接,沒有一個客戶端能夠一直佔用服務端(文件傳輸除外),服務器能夠知足每個客戶端的請求
(2)併發服務器模型:每個客戶端的請求並非由服務器直接處理,並且由服務器的子進程/線程來處理,這樣服務器能夠在同一個時刻響應多個客戶端的請求
例子:學校爲了解決老師沒法同時幫助多個學生解決問題,爲每個學生安排了一名老師進行輔導,可是學校的資源有限,當學生的數量達到必定量時,學校沒法承擔那麼大的開銷。
⭐缺點:沒有從根本上解決循環服務器處理效率低的問題(學校不能無限制的聘請無數個老師)
沒有解決資源利用率低的問題(每位學生不可能一直有問題,可是每一個學生都佔用了一名老師資源)
(3)I/O多路複用模型:內核一旦發現進程指定的一個或者多個IO條件準備讀取時,它就通知該進程。
例子:因爲資源利用率的問題,學校只聘請一名特別資深的教授(具備高端配置的服務器),這名教授處理問題的速度特別快
同時安排一名班長監聽每一個學生有沒有問題,若是有問題,班長就告訴教授,教授就快速的解決這名學生的問題,解決以後進入等待,直到監聽到下一名學生出現問題爲止
這樣,每一個學生的問題都能被即時響應和解決,並且沒有浪費資源
⭐優勢:系統開銷小,沒必要建立和維護進程/線程,從而大大減少了系統的開銷,同時解決了線程阻塞的問題(也可使用到併發服務器的設計中)
【由於socket套接字也是一種文件,socket句柄就是一個文件描述符,因此能夠經過數據結構存儲這些文件描述符,實現通訊的需求】
⭐優勢:跨平臺支持性好,幾乎在全部平臺上都支持
⭐缺點:
⭐優勢:解決了select監聽個數受限的問題
⭐缺點:須要作從用戶態到內核態的轉換,和數據拷貝,效率低,而後輪詢每一個fd的狀態,會經歷屢次無謂的遍歷
沒有解決select中的性能問題,須要輪詢pollfd來獲取就緒的文件描述符,可是同一時刻可能只有少數的客戶端有請求
⭐優勢:不須要作用戶區到內核去的轉換,數據在共享內存中,epoll維護的紅黑樹在共享內存中,內核區和用戶區共同操做共享內存
一、select內部用數組實現,poll用鏈表實現,epoll用紅黑樹來實現
二、select有最大監聽個數的限制,poll和epoll沒有
三、select和poll須要作從內核區到用戶區的轉換,數據拷貝,效率低
epoll不須要,epoll維護的樹及其數據都在共享內存中
## 參考資料:老梁 + 肖家寶同窗的整理 + 個人筆記
(1)文件IO:不帶緩存的IO,也是低級IO,操做系統提供的基本IO服務【不可移植,特定於LINUX平臺/UNIX平臺】
(2)標準IO:是標準函數包和stdio.h頭文件中定義的部分,具備可移植性,提供了三種類型的緩衝區
## 參考文章:https://blog.csdn.net/big_bit/article/details/51804391
HTTP
特色:客戶端發送的每次請求都須要服務器回送響應,在請求結束後,會主動釋放鏈接。從創建鏈接到關閉鏈接的過程稱爲「一次鏈接」。
HTTPS = HTTP over SSL/TLS
是一個安全通訊通道
HTTP是應用層協議,TCP是傳輸層協議,在應用層和傳輸層之間,增長了一個安全套接層SSL(安全套接字層)/TLS(傳輸層安全協議)
SSL使用40 位關鍵字做爲RC4流加密算法
HTTPS的做用:
內容加密 創建一個信息安全通道,來保證數據傳輸的安全;
身份認證 確認網站的真實性
數據完整性 防止內容被第三方冒充或者篡改
HTTP和HTTPS的區別:
## 參考文章:https://blog.csdn.net/WHB20081815/article/details/67640804
ARP:地址解析協議,ARP協議提供了網絡層地址(IP地址)到物理地址(mac地址)之間的動態映射
(1)爲何須要ARP協議
OSI模型把網絡工做分爲七層,每層互不干擾,只經過接口來進行通訊。IP地址在第三層網絡層,MAC地址在第二層數據鏈路層。
協議在發送數據包時,數據包首先是被網卡接收到再去處理上層協議的,因此首先要封裝第三層(IP地址)和第二次(MAC地址)的報頭,可是協議僅知道目的地址IP地址,不知道MAC地址,可是不能跨層通訊
因此須要用到ARP協議
(2)工做過程:
## 參考文章:http://www.javashuo.com/article/p-qauslegb-de.html
URL:統一資源定位符,也就是網絡資源的地址
【例子:你要去旅館找一我的你必須知道他住在那個房間,這時候房間號就是你要找的人對應的地址,也就是這個場景下的URL。】
http://www.example.com:80/path/to/myfile.html?key1=value1&key2=value2#SomewhereInTheDocument
http:// 是協議
www.example.com 是域名,代表正在請求哪一個WEB服務器
:80 是端口號
/path/to/myfile.html 是網絡服務器上資源的路徑
key1=value1&key2=value2 是提供給網絡服務器的額外參數
#SomewhereInTheDocument 是資源自己的另外一部分的錨點(書籤)
## 參考文章:http://www.javashuo.com/article/p-yzjiyyfl-ep.html
1三、在瀏覽器中輸入一串地址發生的過程
1四、DNS解析過程
1五、C/S模型的代碼邏輯
1六、IP怎麼尋址?
OSI七層模型 應用層 表示層 會話層 傳輸層 網絡層 數據鏈路層 物理層
TCP/IP五層模型 應用層 傳輸層 網絡層 數據鏈路層 物理層
TCP/IP四層模型 應用層 傳輸層 網絡層 網絡接口層
應用層:爲特定應用程序提供數據傳輸服務。( TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet)
表示層:對上層信息進行變換,保證一個主機應用層信息被另外一個主機的應用程序理解,表示層的數據轉換包括數據的加密、壓縮、格式轉換。
會話層:管理主機之間的會話進程,即負責創建、管理、終止。
傳輸層:提供端對端的接口。( TCP,UDP)
網絡層:爲數據包選擇路由。(IP,ICMP,ARP,RARP)
數據鏈路層:傳輸有地址的幀,錯誤檢測功能( SLIP,CSLIP,PPP,ARP,RARP,MTU)
物理層:以二進制數據形式在物理媒體上傳輸數據。 ISO2110,IEEE802,IEEE802.2