日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

闭关修炼(十一)网络通信

發布時間:2023/12/14 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 闭关修炼(十一)网络通信 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

你問我互聯網工程設計學了啥?emm。。。感覺上課都在照著抄代碼,要說什么印象特別深,腦海里還真沒剩啥了。


文章目錄

  • 網絡通訊
    • IP
    • 端口號
    • 客戶端和服務端
  • TCP與UDP
    • 什么是網絡模型
    • TCP和UDP的區別
    • 什么是三次握手
    • 什么是四次揮手
    • 為什么建立連接協議是三次握手,而關閉連接卻是四次握手呢?
  • UDP的客戶端與服務端通訊例子
  • TCP的客戶端和服務端


網絡通訊

IP

定位某臺計算機

端口號

定位某個應用程序

客戶端和服務端

發起請求端為客戶端,發送響應端為服務端

TCP與UDP

什么是網絡模型

4層,應用層(HTTP協議),傳輸層(TCP,UDP協議),網絡層(IP協議),鏈路層(以太網協議)

任何計算機語言通訊,底層都使用socket技術

為什么socket支持這么多語言?

socket遵循一個二進制的端口號+IP的規范進行傳輸,所以可以跨語言使用。

socket核心協議:TCP和UDP

TCP和UDP的區別

UDP面向無連接 — 即不建立連接、限制傳輸64k的不可靠協議

TCP面向連接協議,三次握手后進行通訊,通過字節流進行傳輸,效率比UDP低,但比UDP靠譜。

什么是三次握手

當三次握手成功之后,才開始進行數據傳輸。

第一次握手:客戶端:發送報文給服務端,SYN=J

第二次握手:服務端:發送報文給客戶端,ACK=J+1,SYN=K

第三次握手:客戶端:發送報文給服務端,ACK=K+1

什么是四次揮手

結束通信會進行四次揮手。

第一次揮手:客戶端:發送FIN=M

第二次揮手:服務端:發送SYN=M+1

第三次揮手:服務端:發送FIN=N

第四次揮手:客戶端:發送ACK=N+1


為什么建立連接協議是三次握手,而關閉連接卻是四次握手呢?

這是因為服務端的 LISTEN 狀態下的 SOCKET 當收到 SYN 報文的建連請求后,它可以把 ACK 和 SYN(ACK 起應答作用,而 SYN 起同步作用)放在一個報文里來發送。但關閉連接時,當收到對方的 FIN 報文通知時,它僅僅表示對方沒有數據發送給你了,但是你還可以給對方發送數據,也有這么種可能,你還有一些數據在傳給對方的途中,所以你不能立馬關閉連接,也即你可能還需要把在傳輸途中的數據給對方之后,又或者,你還有一些數據需要傳輸給對方后,(再關閉連接)再發送FIN 報文給對方來表示你同意現在可以關閉連接了,所以它這里的 ACK 報文和 FIN 報文多數情況下都是分開發送的。

UDP的客戶端與服務端通訊例子

UDP核心是DatagramSocket和DatagramPacket。

服務端,用DatagramSocket+傳入端口創建服務器,并且建立DatagramPacket來接收客戶端的數據包

import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket;/*** udp服務器** @author uuz* @date 2021/01/11*/ public class UdpServer {/*** 端口號*/static int PORT = 9009;/*** 緩沖區大小*/static int BUFFER_SIZE = 1024;/*** 正在運行*/static boolean IS_RUNNING = true;public static void main(String[] args) throws IOException {System.out.println("UDP SERVER IS RUNNING...");// 創建服務器端口號,默認使用本機ipDatagramSocket datagramSocket = new DatagramSocket(PORT);while (IS_RUNNING) {// 定義數據包byte[] buf = new byte[BUFFER_SIZE];DatagramPacket datagramPacket = new DatagramPacket(buf, buf.length);// 接收客戶端發來的數據,將數據封裝給數據包,此方法阻塞接收datagramSocket.receive(datagramPacket);// 打印來源地址System.out.printf("來源IP地址: %s:%s\n內容: %s\n",datagramPacket.getAddress(),datagramPacket.getPort(),new String(datagramPacket.getData(), 0, datagramPacket.getLength()));}}}

客戶端,構造DatagramPacket,傳入服務器IP和端口,使用datagramSocket發送

import java.io.IOException; import java.net.*;public class UdpClient {static String REMOTE_ADDRESS = "127.0.0.1";public static void main(String[] args) throws IOException {System.out.println("新建Socket客戶端");// 創建一個socket客戶端DatagramSocket datagramSocket = new DatagramSocket();// 要發送的內容String content = "這是一條測試信息";// 轉換成byte[]byte[] bytes = content.getBytes();// 創建數據包,帶上要的發送IP和端口DatagramPacket dp = new DatagramPacket(bytes,bytes.length,InetAddress.getByName(REMOTE_ADDRESS),UdpServer.PORT);datagramSocket.send(dp);datagramSocket.close();System.out.println("發送UDP結束");} }

TCP的客戶端和服務端

服務器端

import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket;/*** tcp服務器** @author uuz* @date 2021/01/11*/ public class TCPServer {static int PORT = 8889;static int BUFFER_SIZE = 1024;static boolean isRunning = true;public static void main(String[] args) throws IOException {System.out.println("TCP SERVER START");// 創建服務器端口號ServerSocket serverSocket = new ServerSocket(PORT);while (isRunning) {// 阻塞接收信息Socket socket = serverSocket.accept();// 獲取socket傳輸的字節流InputStream inputStream = socket.getInputStream();// 將字節流轉為Stringbyte[] bytes = new byte[BUFFER_SIZE];int length = inputStream.read(bytes);// 轉換成StringString data = new String(bytes, 0, length);// 打印輸出System.out.println(data);}serverSocket.close();} }

客戶端

import java.io.IOException; import java.io.OutputStream; import java.net.Socket;public class TCPClient {static String REMOTE_ADDRESS = "127.0.0.1";public static void main(String[] args) throws IOException {System.out.println("tcp 客戶端");// 連接服務器Socket socket = new Socket(REMOTE_ADDRESS, TCPServer.PORT);// 獲取字節流OutputStream outputStream = socket.getOutputStream();// 發送outputStream.write("這是一條測試".getBytes());// 關閉連接socket.close();} }

服務端多線程版

import lombok.AllArgsConstructor; import lombok.Data; import lombok.SneakyThrows;import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;/*** tcp服務器** @author uuz* @date 2021/01/11*/ public class TCPServer {static int PORT = 8889;static int BUFFER_SIZE = 1024;static int THREAD_POOL_SIZE = 10;static boolean isRunning = true;public static void main(String[] args) throws IOException {System.out.println("TCP SERVER START");// 創建服務器端口號ServerSocket serverSocket = new ServerSocket(PORT);// 創建線程池ExecutorService executorService = Executors.newFixedThreadPool(THREAD_POOL_SIZE);while (isRunning) {// 阻塞接收信息Socket socket = serverSocket.accept();executorService.execute(new Runnable() {@SneakyThrows@Overridepublic void run() {// 獲取socket傳輸的字節流InputStream inputStream = socket.getInputStream();// 將字節流轉為Stringbyte[] bytes = new byte[BUFFER_SIZE];int length = inputStream.read(bytes);// 轉換成StringString data = new String(bytes, 0, length);// 打印輸出System.out.println(data);}});}serverSocket.close();}}

總結

以上是生活随笔為你收集整理的闭关修炼(十一)网络通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。