01.30 2020年計算機網絡面試核心

傳輸層控制協議 TCP 簡介

  1. 傳輸層控制協議 TCP 簡介 面向連接的,可靠的,基於字節流的傳輸層通信協議 將應用層的數據流分割成報文段併發送給目標結點的TCP層 數據包都有序號,對方收到則發送ACK確認,未收到則重傳 使用校驗和來檢驗數據在傳輸過程中是否有誤
  2. 報文頭格式


2020年計算機網絡面試核心


TCP Flags: 1. URG:緊急指針標誌 2. ACK:確認序號標誌 3. PSH:push標誌 4. RST:重製連接標誌 5. SYN:同步序號,用於建立連接過程 6. FIN:finish標誌,用於釋放連接

TCP三次握手

“握手”是為了建立連接,TCP三次握手流程圖如下:


2020年計算機網絡面試核心


Question: 說說TCP的三次握手

"握手”是為了建立連接, TCP三次握手的流程圖如下: 在TCP/IP協議中,TCP協議提供可靠的連接服務,採用三次握手建立一個連接。

第一次握手:建立連接時,客戶端發送SYN包[syn=j)到服務器,並進入SYN_SEND狀態,等待服務器確認; 第二次握手:服務器收到SYN 包,必須確認客戶的SYN(ack=j+1) ,同時自己也發送一個SYN 包(syn=k) ,即SYN+ACK包,此時服務器進入SYN_ RECV狀態; 第三次握手:客戶端收到服務器的SYN+ACK包,向服務器發送確認包ACK(ack=k+1),此包發送完畢,客戶端和服務器進入

ESTABLISHED狀態,完成三次握手。

Question: 為什麼需要三次握手才能建立起連接

為了初始化Sequence Number的初始值

Question: 針對SYN Flood的防護措施

首次握手的隱患---SYN超時 ➢SYN隊列滿後,通過tcp_ syncookies參數回發SYN Cookie ➢若為正常連接則Client會回發SYN Cookie ,直接建立連接

Question:建立連接後, Client出現故障怎麼辦

保活機制 ➢向對方發送保活探測報文,如果未收到響應則繼續發送 ➢嘗試次數達到保活探測數仍未收到響應則中斷連接

談談TCP的四次揮手

“揮手”是為了終止連接,TCP四次揮手的流程圖如下:


2020年計算機網絡面試核心


服務器 CLOSE-WAIT:半關閉狀態,客戶端已經沒有數據發送了,但是服務器發送的數據還是可以接收到

Question:談談TCP的四次揮手

"揮手”是為了終止連接, TCP四次揮手的流程圖如下:

第一次揮手: Client發送-一個FIN,用來關閉Client到Server的數據傳送,Client 進入FIN_WAIT_1狀態; 第二次揮手: Server 收到FIN後,發送一個ACK給Client,確認序號為收到序號+1 (與SYN相同,一個FIN佔用一個序 號),Server 進入CLOSE WAIT狀態; 第三次揮手: Server發送- -個FIN,用來關閉Server到Client的數據傳送,Server 進入LAST ACK狀態; 第四次揮手: Client 收到FIN後,Client 進入TIME_WAIT狀態,接著發送一個ACK給Server,確認序號為收到序號+1,Server進入CLOSED狀態,完成四次揮手。

Question: 為什麼會有TIME_WAIT狀態

  1. 確保有足夠的時間讓對方收到ACK包
  2. 避免新舊連接混淆

Question:為什麼需要四次揮手才能斷開連接

因為全雙工,發送方和接收方都需要FIN報文和ACK報文

Question:服務器出現大量CLOSE_ WAIT狀態的原因

對方關閉socket連接,我方忙於讀或寫,沒有及時關閉連接 ➢檢查代碼,特別是釋放資源的代碼 ➢檢查配置,特別是處理請求的線程配置

UDP 簡介


2020年計算機網絡面試核心

2020年計算機網絡面試核心


Question:UDP特點

  1. 面向非連接
  2. 不維護連接狀態,支持同時向多個客戶端傳輸相同的消息
  3. 數據包報頭只有8個字節,額外開銷較小
  4. 吞吐量只受限於數據生成速率、傳輸速率以及機器性能
  5. 盡最大努力交付,不保證可靠交付,不需要維持複雜的鏈接狀態表
  6. 面向報文,不對應用程序提交的報文信息進行拆分或者合併

Question: TCP與UDP的區別

  1. 面向連接vs無連接
  2. 可靠性
  3. 有序性
  4. 速度
  5. 量級

TCP的滑動窗口

Question:RTT和RTO

➢RTT :發送一個數據包到收到對應的ACK ,所花費的時間 ➢RTO :重傳時間間隔

Question:tcp使用滑動窗口做流量控制與亂序重排的作用

  1. 保證TCP的可靠性
  2. 保證TCP的流控特性

window:通知發送方自己能接收的數據域

HTTP簡介

Question:超本文傳輸協議HTTP主要特點

  • 支持客戶/服務器模式
  • 簡單/快速
  • 靈活
  • 無連接
  • 無狀態

Question:HTTP請求結構


2020年計算機網絡面試核心


【請求行,請求頭部,空行,請求正文】

Question:請求/響應的步驟

  • 客戶端連接到Web服務器
  • 發送HTTP請求
  • 服務器接受請求並返回HTTP響應
  • 釋放連接TCP連接
  • 客戶端瀏覽器解析HTML內容

Question:在瀏覽器地址欄鍵入URL,按下回車之後經歷的流程

  1. DNS解析
  2. TCP連接
  3. 發送HTTP請求
  4. 服務器處理請求並返回HTTP報文
  5. 瀏覽器解析渲染頁面
  6. 連接結束

Question:HTTP狀態碼

➢1xx :指示信息--表示請求E接收,繼續處理 ➢2xx :成功--表示請求已被成功接收、理解、接受 ➢3xx :重定向--要完成請求必須進行更進一 步的操作 ➢4xx :客戶端錯誤--請求有語法錯誤或請求無法實現 ➢5xx :服務器端錯誤--服務器未能實現合法的請求

Question:常見狀態碼

200 OK:正常返回信息 400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解 401 Unauthorized:請求未經授權,這個狀態代碼必須和 WWW-Authenticate報頭域一起 使用 403 Forbidden:服務器收到請求,但是拒絕提供服務 404 Not Found:請求資源不存在,eg, 輸入了錯誤的URL 500 Internal Server Error:服務器發生不可預期的錯誤 503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間後可能恢復正常

Question:GET請求與POST請求的區別

從三個層面來解答 ➢Http報文層面: GET將請求信息放在URL , POST放在報文體中 ➢數據庫層面: CET符合冪等性和安全性, POST不符合 ➢其他層面: GET可以被緩存、被存儲,而POST不行

Question:Cookie和Session的區別

Cookie簡介 ➢是由服務器發給客戶端的特殊信息,以文本的形式存放在客戶端 ➢客戶端再次請求的時候,會把Cookie回發 ➢服務器接收到後,會解析Cookie生成與客戶端相對應的內容

2020年計算機網絡面試核心


Session簡介 ➢服務器端的機制,在服務器上保存的信息 ➢解析客戶端請求並操作session id ,按需保存狀態信息


2020年計算機網絡面試核心

➢Cookie數據存放在客戶的瀏覽器上, Session數據放在服務器上 Session相對於Cookie更安全 若考慮減輕服務器負擔,應當使用Cookie

HTTP與HTTPS的區別


2020年計算機網絡面試核心


Question:SSL(Security Sockets Layer ,安全套接層)

➢為網絡通信提供安全及數據完整性的一種安全協議 ➢是操作系統對外的API , SSL3.0後更名為TLS ➢採用身份驗證和數據加密保證網絡通信的安全和數據的完整性

Question:加密的方式

➢對稱加密:加密和解密都使用同一個密鑰 ➢非對稱加密:加密使用的密鑰和解密使用的密鑰是不相同的 ➢哈希算法:將任意長度的信息轉換為固定長度的值,算法不可逆 ➢數字簽名:證明某個消息或者文件是某人發出/認同的

Question:HTTPS數據傳輸流程

➢瀏覽器將支持的加密算法信息發送給服務器 ➢服務器選擇一套瀏覽器支持的加密算法,以證書的形式回發瀏覽器 ➢瀏覽器驗證證書合法性,並結合證書公鑰加密信息發送給服務器 ➢服務器使用私鑰解密信息,驗證哈希,加密響應消息回發瀏覽器 ➢瀏覽器解密響應消息,並對消息進行驗真,之後進行加密交互數據

Question:HTTP與HTTPS的區別

➢HTTPS需要到CA申請證書, HTTP不需要 ➢HTTPS密文傳輸, HTTP明文傳輸 ➢連接方式不同, HTTPS默認使用443端口, HTTP使用80端口 ➢HTTPS=HTTP+加密+認證+完整性保護,較HTTP安全

Question:HTTPS真的很安全嗎

那倒未必 ➢瀏覽器默認填充http:// ,請求需要進行跳轉,有被劫持的風險 ➢可以使用HSTS ( HTTP Strict Transport Security )優化

Socket簡介

Socket是對TCP/IP協議的抽象,是操作系統對外開放的接口


2020年計算機網絡面試核心


Socket通信流程


2020年計算機網絡面試核心


Question:編寫一個網絡應用程序,有客戶端與服務器端,客戶端向服務器發送-一個字符串,服務器收到該字符串後將其打印到命令行上,然後向客戶端返回該字符串的長度,最後,客戶端輸出服務器端返回的該字符串的長度,分別用TCP和UDP兩種方式去實現

<code>public class LengthCalculator extends  Thread{
private Socket socket;

public LengthCalculator(Socket socket){
this.socket=socket;
}

@Override
public void run(){
try{
OutputStream os =socket.getOutputStream();
InputStream is =socket.getInputStream();
int ch=0;
byte[] buff =new byte[1024];
ch=is.read(buff);
String content =new String(buff,0,ch);
System.out.println(content);
os.write(String.valueOf(content.length()).getBytes());
is.close();
os.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

public class TCPClient {
public static void main(String[] args) throws IOException {
Socket socket =new Socket("127.0.0.1",65000);
OutputStream os =socket.getOutputStream();
InputStream is =socket.getInputStream();
os.write(new String("hello world").getBytes());

int ch=0;
byte[] buff =new byte[1024];
ch=is.read(buff);
String content =new String(buff,0,ch);
System.out.println(content);
is.close();
os.close();
socket.close();
}
}

public class TCPServer {
public static void main(String[] args) throws IOException {
ServerSocket ss =new ServerSocket(65000);
while(true){
Socket socket=ss.accept();
new LengthCalculator(socket).start();
}
}
}

public class UDPClient {
public static void main(String[] args) throws IOException {
DatagramSocket socket =new DatagramSocket();
byte[] buf ="hello world".getBytes();
//將IP封裝為InetAddress對象
InetAddress address =InetAddress.getByName("127.0.0.1");
//將要發送數據封裝成DatagramPacket對象,填寫上ip地址與端口號
DatagramPacket packet =new DatagramPacket(buf,buf.length,address,65001);
socket.send(packet);

byte[] data =new byte[100];
//創建DatagramPacket對象來存儲服務端發送的數據
DatagramPacket receivedPacket = new DatagramPacket(data,data.length);
socket.receive(receivedPacket);
//將數據取出來並打印
String content = new String(receivedPacket.getData(),0,receivedPacket.getLength());
System.out.println(content);
}
}

public class UDPServer {
public static void main(String[] args) throws IOException {
//服務端接收客戶端發送的數據報

DatagramSocket socket =new DatagramSocket(65001);
//存儲從客戶端收到的內容
byte[] buff =new byte[100];
//接收客戶端發送的內容,並將內容封裝進DatagramPacket對象中
DatagramPacket packet =new DatagramPacket(buff,buff.length);
socket.receive(packet);
//從DatagramPacket中獲取真正存儲的數據
byte[] data =packet.getData();
//將數據從二進制轉化為字符串形式
String content =new String(data,0,packet.getLength());
System.out.println(content);
//將要發送給客戶端的數據換成二進制
byte[] sendedContent =String.valueOf(content.length()).getBytes();
//服務端給客戶端發送數據報
//從DatagramPacket對象中獲取到數據的來源地址與端口號
DatagramPacket packetToClient =new DatagramPacket(sendedContent,sendedContent.length,packet.getAddress(),packet.getPort());
socket.send(packetToClient);
}
}/<code>

最後,小編想說:我是一名python開發工程師,

整理了一套最新的python系統學習教程,

想要這些資料的可以關注私信小編“01”即可(免費分享哦)希望能對你有所幫助


分享到:


相關文章: