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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

TCP与UDP通信协议及Java实现

發布時間:2025/7/14 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 TCP与UDP通信协议及Java实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

概述

TCP (Transmission Control Protocol):傳輸控制協議
UDP(User Datagram Protocol):用戶數據報協議

TCP 與 UDP 都是 運輸層(Transport Layer)上的因特網協議,運輸層協議的功能就是為運行在不同主機上的應用進程之間提供 邏輯通信 ,使得運行不同進程的主機即使分隔于地球兩側,也能像是直接相連一樣。
而具體做法是,它為來自應用層的報文添加上運輸層首部來創建運輸層報文段,這個首部中包含了以下信息

通過這些首部字段,不同主機之間的進程就可以通信了

UDP 為調用它的應用程序提供了一種 不可靠的 無連接 服務
TCP 為調用它的應用程序提供了一種 可靠的 面向連接 服務

UDP

UDP 可以說是一種極簡的運輸層協議,它的功能僅僅包括運輸層必備的功能,即:多路復用/多路分解,差錯檢測
在后面的講解中我們會知道 TCP 進行通信時,發送方與接收方先要進行“三次握手”來確認連接,而 UDP 則沒有這一流程,所以說 UDP 是無連接
在 TCP 中,如果消息沒有成功發送,發送方是會收到發送失敗的反饋的,而 UDP 中,發送方發出數據后無法確認是否成功發送,只能靠接收方是否回復信息來確認上一次發送成功與否,因此在應用 UDP 時,通常會加入一個延時,如果超過額定時間未收到回復,就重新發送
DNS(Domain Name System,域名系統)就是一個應用 UDP 的例子,當我們輸入網址訪問網站時,DNS 就是通過 UDP 發送域名查詢報文的。所以,如果長時間沒有得到回復,我們就會看到“連接超時”的錯誤頁面。

UDP 檢驗和,就是用來做差錯檢驗的數據。
方法實現是,發送方的 UDP 對報文段中的所有 16 比特字的和進行反碼運算,求和時遇到溢出要回卷。
例:有 3 個 16 比特字
0110 0110 0110 0000
0101 0101 0101 0101
1000 1111 0000 1100
①:前兩個相加
0110 0110 0110 0000
0101 0101 0101 0101
————————————
1011 1011 1011 0101
②:和與第三個相加
1011 1011 1011 0101
1000 1111 0000 1100
————————————
(1)0100 1010 1100 0001
③:有溢出,進行回卷
0100 1010 1100 0001 + 1 = 0100 1010 1100 0010
④:轉為反碼,存入檢驗和
1011 0101 0011 1101
接收端收到數據后,會再次將數據取和,再與檢驗和相加,若結果為1111 1111 1111 1111則表示無差錯,若出現 0 則表示有差錯

UDP 雖然提供差錯檢測,但是不會進行錯誤修復,它要么直接丟棄錯誤段,要么將錯誤段上報應用程序

看到這里,不由得會產生一個疑問:UDP 這么的精簡,功能不夠強大,為什么還要用它呢?
原因是:

  • 應用層能更好的控制要發送的數據和發送時間,實時性
  • 無需建立連接,反應迅速
  • 無連接狀態,不需要維護連接狀態,節省資源
  • 分組首部開銷小,節省數據段空間

  • TCP

    應用 TCP 時,一個應用進程可以開始向另一個應用進程發送數據之前,這兩個進程必須先進行“握手”,所以說,TCP 是面向連接的
    TCP 連接提供的是 點對點,全雙工服務
    TCP 提供的是 可靠數據傳輸
    TCP 通過使用 流量控制、序號、確認和定時器 等技術,確保正確地、按序地將數據從發送進程交付給接收進程
    TCP 還提供了 擁塞控制 ,它允許 TCP 連接通過一條擁塞的網絡鏈路,平等地共享網絡鏈路帶寬。

    TCP 建立連接有三次握手

    終止連接有四次握手

    TCP 報文段結構


    代碼示例

    UDP

    UDPClient.java

    package test;import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress;/** * UDPCLient deom* @author <dht925nerd@126.com>*/ public class UDPClient {public static void main(String[] args) throws Exception {DatagramSocket clientSocket = new DatagramSocket();BufferedReader inFromUser =new BufferedReader(new InputStreamReader(System.in));//獲取本地 IP 地址InetAddress IPAddress = InetAddress.getLocalHost();byte[] sendData;byte[] receiveData = new byte[1024];System.out.println("請輸入一句英文,服務器會返回其大寫形式(輸入exit退出)");while (true) {String sentence = inFromUser.readLine();if (sentence.equals("exit")) break;sendData = sentence.getBytes();//創建發送數據報包,并標注源地址#,目的地址#DatagramPacket sendPacket =new DatagramPacket(sendData, sendData.length, IPAddress, 9876);//發送數據報包clientSocket.send(sendPacket);//創建接收數據報包DatagramPacket receivePacket =new DatagramPacket(receiveData, receiveData.length);//接收服務器的數據報包clientSocket.receive(receivePacket);String modifiedSentence = new String(receivePacket.getData());System.out.println("FROM SERVER: " + modifiedSentence);}clientSocket.close();} }

    UDPServer.java

    package test;import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.text.SimpleDateFormat; import java.util.Date;/*** UDPServer Demo* @author <dht925nerd@126.com>*/ public class UDPServer {public static void main(String[] args) throws Exception {DatagramSocket serverSocket =new DatagramSocket(9876);byte[] sendData;SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");while (true) {byte[] receiveData = new byte[1024];//創建接收數據報包DatagramPacket receivePacket =new DatagramPacket(receiveData, receiveData.length);//接收客戶端數據報包serverSocket.receive(receivePacket);String sentence = new String(receivePacket.getData());//獲取客戶端地址InetAddress IPAddress = receivePacket.getAddress();if (sentence != null) System.out.println(df.format(new Date()) + " from " + IPAddress + ": " + sentence );//獲得客戶端端口號int port = receivePacket.getPort();String capitalizedSentence = sentence.toUpperCase();sendData = capitalizedSentence.getBytes();DatagramPacket sendPacket =new DatagramPacket(sendData, sendData.length, IPAddress, port);//向客戶端發送數據報包serverSocket.send(sendPacket);}} }

    測試方法:
    ① 先編譯運行UDPServer.java
    ② 再運行 UDPClient.java
    ③ 在UDPClient的控制板面輸入字符串,回車
    ④ 在UDPClient 和 UDPServer 控制板面觀察運行信息

    運行信息:
    客戶端

    服務器端

    TCP

    TCPClient.java

    package test;import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.Socket;/*** TCPClient demo* @author <dht925nerd@126.com>*/ public class TCPClient {public static void main(String[] args) throws Exception {String sentence;String modifiedSentence;System.out.println("請輸入一個英文字符串,服務器將返回其大寫形式(輸入exit退出)");while (true) {BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));//創建客戶端 Socket 并指明需要連接的服務器端的主機名及端口號Socket clientSocket = new Socket("localhost", 6789);DataOutputStream outToServer = new DataOutputStream(clientSocket.getOutputStream());BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));sentence = inFromUser.readLine();if (sentence.equals("exit")) break;//向服務器發送數據outToServer.writeBytes(sentence + '\n');//接收服務器返回數據modifiedSentence = inFromServer.readLine();System.out.println("FROM SERVER: " + modifiedSentence);clientSocket.close();}} }

    TCPServer.java

    package test;import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import java.text.SimpleDateFormat; import java.util.Date;/*** TCPServer demo* @author <dht925nerd@126.com>*/ public class TCPServer {public static void main(String[] args) throws Exception {String clientSentence;String capitalizedSentence;SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//創建服務器端 Socket 并指明端口號ServerSocket welcomeSocket = new ServerSocket(6789);while(true) {//接收客戶端連接Socket connectionSocket = welcomeSocket.accept();BufferedReader inFromClient = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));DataOutputStream outToClient = new DataOutputStream(connectionSocket.getOutputStream());//獲取客戶端傳入的字符串clientSentence = inFromClient.readLine();if (clientSentence != null)System.out.println(df.format(new Date()) + " from " + connectionSocket.getInetAddress() + ": " + clientSentence );capitalizedSentence = clientSentence.toUpperCase() + '\n';//向客戶端發送修改后的字符串outToClient.writeBytes(capitalizedSentence);}} }

    測試方法:同上

    總結

    以上是生活随笔為你收集整理的TCP与UDP通信协议及Java实现的全部內容,希望文章能夠幫你解決所遇到的問題。

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