傳輸層
定義一些傳輸數據的協議和端口,傳輸協議同時進行流量控制,根據接收方的數據吞入熟讀,規定適當的發送速率,解決傳輸效率及能力問題
什么是TCP
TCP/IP即傳輸控制/網絡協議,是面向連接的協議,發送數據前要先建立連接(發送方和接收方的成
對的兩個之間必須建 立連接),TCP提供可靠的服務,也就是說,通過TCP連接傳輸的數據不會丟
失,沒有重復,并且按順序到達
TCP是怎么建立服務端與客戶端雙向通信可信型通道的
TCP三次握手是建立TCP連接的過程,用于確認客戶端和服務器之間的發送和接收功能是否正常。以下是TCP三次握手的具體細節:
- 第一次握手:客戶端向服務器發送一個SYN包(即同步序列號),并進入SYN_SENT狀態,等待服務器的確認。此時,SYN=1,seq=x(seq為客戶端發送的序列號),表示客戶端請求與服務器建立連接。
- 第二次握手:服務器收到客戶端發送的SYN包后,會確認客戶的ACK(即確認號),ack=x+1,同時自己也發送一個SYN包,即SYN+ACK包,此時服務器進入SYN_RECV狀態。SYN=1,ACK=1,seq=y(seq為服務器發送的序列號),ack=x+1,表示服務器已收到客戶端的連接請求,并請求客戶端確認。
- 第三次握手:客戶端收到服務器的SYN+ACK包后,會向服務器發送一個確認包ACK,ack=y+1,此包發送完畢,客戶端和服務器進入ESTABLISHED狀態,完成三次握手。此時,客戶端和服務器都知道彼此有收發能力,可以開始傳輸數據了。
在三次握手過程中,每個數據包都包含一個序列號(seq)和一個確認號(ack)。序列號用于標識發送方發送的數據包的順序,而確認號則用于確認接收方已成功接收到的數據包的順序。通過比較序列號和確認號,雙方可以確保數據的正確傳輸和接收。
此外,值得注意的是,在第二次和第三次握手中,服務器和客戶端都會發送SYN和ACK標志位都為1的數據包,這是因為SYN和ACK標志位在不同的階段有不同的含義。在第二次握手中,服務器的SYN標志位表示它正在請求與客戶端建立連接,而ACK標志位則表示它已接收到客戶端的連接請求。在第三次握手中,客戶端的SYN標志位已不再需要,因為連接已經建立,而ACK標志位則用于確認已接收到服務器的SYN+ACK包。
總之,TCP三次握手是一個非常重要的過程,用于確保客戶端和服務器之間的連接是可靠的,并且可以正常地傳輸數據。通過三次握手,雙方可以確認彼此的發送和接收功能是否正常,并建立穩定的連接。
用打電話(IM的信令)來比喻三次握手
甲給乙打電話
?第一次握手? 甲撥打乙的電話,乙的手機接收到甲的通話請求? ? 服務器確認客戶端發送正常
第二次握手? ?乙的手機會同步返回一個信令,告訴甲的手機,大哥,我收到了你的信息哦,客戶端確認自己發送和接收與服務器發送和接收都正常,此時服務器只知道自己接收正常不知道自己發送是否正常
第三次握手? ?甲的手機接收到這個信令后,確認了乙的手機可以呼叫的通,繼續呼叫(重點是怎么確定是繼續呼叫還是第一次呼叫,這也就是那些丟來丟去的數據包做的事情),客戶端繼續呼叫了,服務器收到它的繼續呼叫,說明自己也發送成功了,確認了雙方都收發正常,可以建立正常的通訊了
這三次握手是缺一不可的,只要缺少就無法保證雙向的接收都正常
?實際上以上就已經是建立了可信型通訊通道了,你實際上通訊的拒接或者收聽都是建立在這個通訊通道建立的后續操作了
使用TCP協議的協議
使用TCP(傳輸控制協議)的協議有很多,以下是一些常見的例子:
- HTTP:超文本傳輸協議,用于在Web瀏覽器和服務器之間傳輸數據。
- HTTPS:安全超文本傳輸協議,是HTTP的安全版本,使用SSL/TLS對數據進行加密。
- FTP:文件傳輸協議,用于在客戶端和服務器之間傳輸文件。
- POP3:郵局協議,用于從郵件服務器接收電子郵件。
- SMTP:簡單郵件傳輸協議,用于發送電子郵件。
- Telnet:遠程登錄協議,允許用戶通過終端登錄到遠程計算機。
- SSH:安全外殼協議,用于加密安全登錄,替代安全性較差的Telnet協議。
以上只是使用TCP協議的一部分協議,實際上還有很多其他的協議也使用TCP進行數據傳輸。TCP是一種面向連接的、可靠的、基于字節流的傳輸層通信協議,廣泛應用于各種網絡應用中。
TCP例子
package com.zxs;import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;public class TCPServer {public static void main(String[] args) {try {ServerSocket server = new ServerSocket(8081);System.out.println("等待客戶端連接...");while (true) {Socket socket = server.accept();System.out.println("客戶信息為:" + socket.getRemoteSocketAddress());InputStream in = socket.getInputStream();byte[] buffer = new byte[1024];int len = 0;while ((len = in.read(buffer)) > 0) {System.out.println(new String(buffer, 0, len));}OutputStream out = socket.getOutputStream();out.write("1".getBytes());}} catch (IOException e) {e.printStackTrace();}}
}
?
package com.zxs;import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;public class TCPClient {public static void main(String[] args) throws IOException {Socket socket = new Socket("127.0.0.1", 8081);OutputStream outputStream = socket.getOutputStream();System.out.println("連接成功請輸入:");while (true) {byte[] car = new Scanner(System.in).nextLine().getBytes();outputStream.write(car);outputStream.flush();}}
}
什么是UDP
UDP它是屬于TCP/IP協議族中的一種。是無連接的協議,發送數據前不需要建立連接,是沒有可
靠性的協議。因為不需要建立連接所以可以在在網絡上以任何可能的路徑傳輸,因此能否到達目的
地,到達目的地的時間以及內容的正確性都是不能被保證的。
我只負責公告,能不能收到是你們自己的事情
UDP(User Datagram Protocol)是用戶數據報協議,它是OSI(Open System Interconnection,開放式系統互聯)參考模型中一種無連接的傳輸層協議,提供面向事務的簡單不可靠信息傳送服務。UDP協議主要用于不要求分組順序到達的傳輸中,分組傳輸順序的檢查與排序由應用層完成。
UDP協議的主要特點包括:
- 面向無連接的協議,速度快但是不可靠。
- 只管發送數據,不確認對方是否收到,對方接收到數據之后也不會反饋一個信息給發送方。
- 基于數據包(報)傳輸:將要發送的數據,源和目的地址封裝的數據包中。
- 數據包大小限制在64k以內。
用公司發送放假通知來比喻UDP的不負責
假如到了年底放假,具體什么時候放假,人事在群里發一個放假通知,你Y的加沒加群屏沒屏蔽,收沒收到不關他的事,他反正是通知了
使用UDP協議的協議
使用UDP(用戶數據報協議)的協議主要有:
- DNS(域名系統):DNS用于將域名轉換為IP地址。由于DNS查詢和響應通常較小,且不需要建立持續的連接,因此DNS使用UDP進行通信。
- TFTP(簡單文件傳輸協議):這是一種簡單的文件傳輸協議,通常用于嵌入式系統和網絡設備的固件更新。TFTP使用UDP進行數據傳輸。
- RIP(路由信息協議):RIP是一種用于在自治系統(AS)內部網關之間傳遞路由信息的動態路由選擇協議。RIP使用UDP進行通信。
- DHCP(動態主機配置協議):DHCP用于自動為網絡中的主機分配IP地址。DHCP客戶端和服務器之間使用UDP進行通信。
- SNMP(簡單網絡管理協議):SNMP用于網絡管理系統收集和管理網絡設備的信息。SNMP使用UDP進行通信。
此外,還有一些實時性要求較高、數據量較小的應用場景也會使用UDP協議,例如網絡視頻會議系統、在線視頻、網絡語音電話等。
需要注意的是,雖然這些協議使用UDP進行通信,但并不意味著它們完全不依賴TCP。在某些情況下,這些協議可能會使用TCP進行輔助通信,例如當需要建立連接或進行可靠的數據傳輸時。
UDP例子
package com.zxs;import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;//UDP協議Socket:服務端
public class UDPServer {public static void main(String[] args) {try {DatagramSocket socket = new DatagramSocket(8082);System.out.println("服務端準備中...");while (true) {byte[] car = new byte[1024];DatagramPacket packet = new DatagramPacket(car, car.length);socket.receive(packet);int length = packet.getLength();System.out.println("接收到的數據:" + new String(car, 0, length));System.out.println("UDP協議Socket接受成功");}} catch (IOException e) {e.printStackTrace();}}
}
package com.zxs;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.Scanner;public class UDPClient {public static void main(String[] args) {try {DatagramSocket socket = new DatagramSocket(2468);InetSocketAddress address = new InetSocketAddress("127.0.0.1", 8082);System.out.println("請輸入你要公告的信息:");while (true) {byte[] car = new Scanner(System.in).nextLine().getBytes();DatagramPacket packet = new DatagramPacket(car, car.length,address);socket.send(packet);System.out.println("UDP協議的Socket發送成功");}} catch (Exception e) {e.printStackTrace();}}
}