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

歡迎訪問 生活随笔!

生活随笔

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

java

基于Java的TCP Socket通信详解

發布時間:2023/12/20 java 57 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于Java的TCP Socket通信详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

TCP Socket通信是一種比較常用的基于連接的網絡通信方式。本文通過Java實現TCP Socket通信,并將其用于計算機端,Android手機端,硬件設備端,同時做到代碼規范化,實現代碼最大化復用。

| 本文代碼可在GitHub下載,建議對照源碼閱讀文章 https://github.com/IVanMissAya/tcp_server

TCP連接的建立

客戶端和服務器間通過 三次握手 建立TCP連接。在Java中,連接建立完成后,服務器端和客戶端分別獲取到一個Socket實例,之后就可以通過這個Socket實例進行通信。服務器端和客戶端使用不同的方法獲取Socket實例。

  • 服務器端

    在服務器端,通過ServerSocket實現對指定端口的監聽,代碼如下。其中port為int型端口數值,取值065535,01024為系統保留端口,這里取值1234。如果發生錯誤將會拋出異常。

    int port = 1234; ServerSocket server = new ServerSocket(port);

    通過ServerSocket.accept()方法接受客戶端連接。這個方法是阻塞的,從調用時開始監聽端口,直到客戶端連接建立時,執行結束并返回Socket實例。連接建立失敗會拋出異常。

    Socket socket = server.accept();
  • 客戶端

    客戶端直接通過實例化的形式,產生Socket實例。實例化的過程中,嘗試連接指定的服務器主機。連接成功則實例化完成,連接失敗則拋出異常。hostIP為主機的IP地址,port為端口號,和服務器主機監聽的端口號保持一致。

    String hostIP = "127.0.0.1"; int port = 1234; Socket socket = new Socket(hostIP, port);
  • 連接的建立過程

    以上代碼的執行順序是:

    • 服務器端實例化ServerSocket:new ServerSocket(port);
    • 服務器端執行accept(),監聽指定端口,此方法阻塞等待客戶端連接:server.accept();
    • 客戶端實例化Socket實例,嘗試連接服務器:new Socket(hostIP, port);
    • TCP三次握手成功,服務器端的accept()返回Socket實例,同時客戶端的Socket實例化成功。

    Socket的讀寫

    以收發字符串為例來說明Socket的讀寫。

    向Socket對象寫入數據,則會發送至TCP連接的另一方。這個操作在服務器端和客戶端是一樣的。可通過獲取Socket的輸出流來寫入UTF8格式編碼的字符串,代碼如下。寫入完成后,就會被發送到連接的另一端。

    private DataOutputStream out; out = new DataOutputStream(socket.getOutputStream()); String s = "Test"; out.writeUTF(s); out.flush();

    在接收端,通過獲取Socket的輸入流,就可以讀取字符串數據,代碼如下。readUTF()方法是阻塞的,直到對方發送完一個字符串,該方法才會執行結束并返回收到的字符串。如果連接中斷,或強制關閉Socket的輸入流,即執行socket.shutdownInput(),該方法會拋出異常。

    private DataInputStream in; in = new DataInputStream(socket.getInputStream()); String s = in.readUTF();

    在建立了TCP連接后,由于無法確定對方的數據發送時間,為了保證及時接收到數據,通過一個新線程不斷調用in.readUTF()方法讀取數據(相當于輪詢法);并在接收到數據后回調相關函數,對數據進行處理。

    TCP連接的斷開

    TCP Socket連接是雙向的,通過 四次揮手 的方式斷開,雙方分別調用Socket.close()方法斷開連接。連接斷開的過程中,一般一方A先斷開連接,另一方B發現A斷開連接后,也斷開連接。為方便表述,將先斷開連接的一方A稱為“主動斷開連接”;后斷開的一方B,則為“被動斷開連接”。

    在一方B阻塞執行in.readUTF()方法時,如果對方A主動斷開Socket連接,這個方法會拋出異常。從而在B處理異常時,可以被動的斷開這邊的連接。

    為保證主動斷開連接的一方不會阻塞在in.readUTF()方法中,需要先執行socket.shutdownInput()。所以主動斷開連接的代碼如下。

    socket.shutdownInput(); in.close(); socket.close();

    被動斷開連接的一方,在捕獲到in.readUTF()的異常后,斷開Socket連接。

    try {String s = in.readUTF(); } catch (IOException e) {// 連接被斷開(被動)try {in.close();socket.close();in = null;socket = null;} catch (IOException e) {e.printStackTrace();} }

    SocketTransceiver的實現

    考慮到在服務器端和客戶端,Socket對象的操作是完全一樣的,所以實現了一個SocketTransceiver(收發器),實現對Socket的直接操作,其他代碼則通過SocketTransceiver間接操作Socket對象實現數據收發、斷開連接等。

    SocketTransceiver實現的功能有:

    • 開啟新線程不斷查詢Socket是否收到數據;
    • 將字符串、文件等類型的數據進行打包,并通過Socket發送;
    • 從Socket接收數據,并自動解析出數據(字符串、文件等),接收完成后回調相應的方法;
    • 在發生錯誤、連接被動斷開時,自動斷開連接并進行相關處理,并回調相應方法。
      SocketTransceiver.class 使用抽象類實現,回調方法是抽象的,實例化時對抽象方法進行實現,處理回調。完整代碼見附件。

    TcpServer的實現

    TcpServer為TCP Socket服務器端程序。為了讓服務器能同時接受并處理來自多個客戶端的TCP連接請求:

    • TcpServer中用一個監聽線程對端口進行監聽,即阻塞執行server.accept()方法,等待接受客戶端連接;
    • 服務器端每次與一個客戶端建立連接,即accept()方法執行結束并返回一個Socket對象,就會用一個SocketTransceiver對這個Socket進行操作;
    • 連接建立后,監聽線程再次執行server.accept()方法,繼續監聽端口并等待下一個連接;
    • 服務器端有一個List,保存當前連接的每個客戶端對應的SocketTransceiver對象,在需要時可取出并進行操作。

    TcpClient的實現

    TcpClient為TCP Socket客戶端程序。主要工作是進行Socket的連接,并利用SocketTransceiver對Socket進行操作。

    另附 windows 下tcp 測試工具

  • sokit 是一款開源免費的 TCP / UDP 測試(調試)工具, 可以用來接收,發送或轉發TCP/UDP數據包。 下載地址: http://sqdownd.onlinedown.net/down/sokit-1.3-win32-chs.zip

  • TCPUDP測試工具用于開發網絡通訊程序時,在服務器或客戶端測試TCP/UDP通訊連接和測試數據的接收和發送情況。 下載地址: http://fastsoft.onlinedown.net/down/TCPUDPDebug102_Setup.exe

  • 總結

    以上是生活随笔為你收集整理的基于Java的TCP Socket通信详解的全部內容,希望文章能夠幫你解決所遇到的問題。

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