最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 實現(xiàn)簡單Socket 通信的示例

 更新時間:2021年03月03日 10:28:25   作者:Robothy  
這篇文章主要介紹了Java 實現(xiàn)簡單Socket 通信的示例,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下

Java socket 封裝了傳輸層的實現(xiàn)細(xì)節(jié),開發(fā)人員可以基于 socket 實現(xiàn)應(yīng)用層。本文介紹了 Java socket 簡單用法。

1. 傳輸層協(xié)議

傳輸層包含了兩種協(xié)議,分別是 TCP (Transmission Control Protocol,傳輸控制協(xié)議) 和 UDP (User Datagram Protocol,用戶數(shù)據(jù)報協(xié)議)。

TCP 是一種面向連接,可靠的流協(xié)議。通信雙方在“發(fā)送-接收”數(shù)據(jù)之前需要先建立 TCP 連接,然后通過互相發(fā)送二進制數(shù)據(jù)流來進行通信。所謂連接,指的是各種設(shè)備、線路,或網(wǎng)絡(luò)中進行通信的應(yīng)用程序為了相互傳遞消息而建立的專有、虛擬的通信線路。連接一旦建立,進行通信的應(yīng)用程序只使用該虛擬的通信線路發(fā)送和接收數(shù)據(jù)。TCP 還需要處理端到端之間的流量控制。

UDP 是一種無連接的,不可靠的數(shù)據(jù)報協(xié)議。發(fā)送方不需要與接收方建立連接,通信雙方通過發(fā)送一個個獨立的數(shù)據(jù)報來進行通訊。

TCP 通過序列號、確認(rèn)應(yīng)答、數(shù)據(jù)校驗等機制確保了傳輸?shù)目煽啃?,適用于需要可靠數(shù)據(jù)傳輸?shù)膱鼍埃瑧?yīng)用層協(xié)議 HTTP,F(xiàn)TP 基于 TCP。UDP 沒有復(fù)雜的控制機制,不糾錯,不重發(fā),不保證數(shù)據(jù)的準(zhǔn)確性,不確保數(shù)據(jù)到達(dá)目的地;不過 UDP 傳送等量數(shù)據(jù)花費更小的流量,適用于對時延要求高但對準(zhǔn)確性要求不高的場景,如視頻、音頻通訊。

Java 中有 3 種套接字類,java.net.Socket 和 java.net.ServerSocket 基于 TCP,java.net.DatagramSocket 基于 UDP。

2. TCP 示例

TCP 是面向連接的,所以在進行通訊之前發(fā)送端(客戶端)需要先連接到接收端(服務(wù)端)。客戶端通過 new Socket("localhost", 9090) 來創(chuàng)建一個連接到服務(wù)端的套接字,這個套接字連接到主機 localhost 的 9090 端口。

ServerSocket 實現(xiàn)服務(wù)端套接字,通過 new ServerSocket(9090) 來創(chuàng)建一個監(jiān)聽端口為 9090 實例;ServerSocket.accept() 方法會阻塞等待客戶端的連接,一旦有連接過來,會返回一個服務(wù)端的 Socket 實例。連接建立完成,客戶端 Socket 實例和服務(wù)端 Socket 實例就可以面向輸入輸出流發(fā)送數(shù)據(jù)了。

2.1 示例效果

客戶端程序接收控制臺輸入的內(nèi)容,客戶端控制臺每輸入一行,就往服務(wù)端發(fā)送,服務(wù)端接收到消息之后,將消息打印到控制臺。

客戶端輸入 "Bye" 時,客戶端斷開與服務(wù)端的連接,客戶端程序退出,服務(wù)端程序繼續(xù)等待連接。

客戶端控制臺輸入輸出:

$ java Server.java
Bind Port 9090
New client connected.
Received Message --> Are you OK!

服務(wù)端控制臺輸出:

$ java Client.java
Are you OK!
Send Msg --> Are you OK!
Bye
$

2.2 服務(wù)端程序代碼

import java.net.*;
import java.io.*;

class Server {
 
 public static void main(String[] args) {
  // ServerSocket 實現(xiàn)了 AutoCloseable 接口,所以支持 try-with-resource 語句
  // 創(chuàng)建一個 ServerSocket,監(jiān)聽 9090 端口
  try(ServerSocket serv = new ServerSocket(9090)){
   System.out.printf("Bind Port %d\n", serv.getLocalPort());
   Socket socket = null;
   while(true){
    // 接收連接,如果沒有連接,accept() 方法會阻塞
    socket = serv.accept();
    
    // 獲取輸入流,并使用 BufferedInputStream 和 InputStreamReader 裝飾,方便以字符流的形式處理,方便一行行讀取內(nèi)容
    try(BufferedReader in = new BufferedReader( new InputStreamReader(socket.getInputStream()) )){
     String msg = null;
     char[] cbuf = new char[1024];
     int len = 0;
     while( (len = in.read(cbuf, 0, 1024)) != -1 ){ // 循環(huán)讀取輸入流中的內(nèi)容
      msg = new String(cbuf, 0, len);
      if("Bye".equals(msg)) { // 如果檢測到 "Bye" ,則跳出循環(huán),不再讀取輸入流中內(nèi)容。
       break;
      }
      System.out.printf("Received Message --> %s \n", msg);
     }
    }catch (IOException e){
     e.printStackTrace();
    }
    
   }
   
  }catch (IOException e){
   e.printStackTrace();
  }
 }
}
2.3 客戶端程序代碼
import java.net.*;
import java.io.*;
import java.util.*;

class Client{
 
 public static void main(String[] args){
  
  try(Socket socket = new Socket("localhost", 9090)){
   BufferedWriter out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
   Scanner scanner = new Scanner(System.in);
   scanner.useDelimiter("\r\n");
   String msg = null;
   while( !(msg = scanner.next()).equals("Bye") ){
    System.out.printf("Send Msg --> %s \n", msg);
    out.write(msg);
    out.flush(); // 立即發(fā)送,否則需要積累到一定大小才一次性發(fā)送
   }
  }catch (IOException e){
   e.printStackTrace();
  }
  
 }
 
}

3. UDP 示例

UDP 不需要連接,客戶端與服務(wù)端通過發(fā)送數(shù)據(jù)報來完成通信。Java 中使用 java.net.DatagramSocket 來表示 UDP 客戶端或服務(wù)端的套接字,使用 java.net.DatagramPacket 來表示 UDP 的數(shù)據(jù)報。客戶端和服務(wù)端可以直接向?qū)Ψ桨l(fā)送數(shù)據(jù)報,不需要進行連接。

下面代碼基于 UDP 實現(xiàn)了與上面程序同樣的功能。不過消息可能會出錯,某些消息可能也不能到達(dá)服務(wù)端。

3.1 服務(wù)端程序代碼

import java.net.*;
import java.io.*;

class Server {
 
 public static void main(String[] args){
  
  // 創(chuàng)建一個 DatagramPacket 實例,用來接收客戶端發(fā)送過來的 UDP 數(shù)據(jù)報,這個實例可以重復(fù)利用。
  byte[] buf = new byte[8192]; // 緩存區(qū)
  int len = buf.length;  // 要利用的緩存區(qū)的大小
  DatagramPacket pac = new DatagramPacket(buf, len);
  
  // 創(chuàng)建服務(wù)端的套接字,需要指定綁定的端口號
  try(DatagramSocket serv = new DatagramSocket(9191)){
   
   while(true){
    serv.receive(pac); // 接收數(shù)據(jù)報。如果沒有數(shù)據(jù)報發(fā)送過來,會阻塞
    System.out.println("Message --> " + new String(pac.getData(), 0, pac.getLength()));
   }
   
  }catch (IOException e){
   e.printStackTrace();
  }
 }
 
}

3.2 客戶端程序代碼

import java.io.*;
import java.net.*;
import java.util.*;

class Client {
 public static void main(String[] args){
  
  // 創(chuàng)建一個客戶端的 UDP 套接字,不需要指定任何信息
  try(DatagramSocket client = new DatagramSocket()){
   
   // 創(chuàng)建一個數(shù)據(jù)報實例,數(shù)據(jù)和長度在發(fā)送之前都會重新設(shè)置,所以這里直接置為 0 即可。 
   // 由于是發(fā)送端,所以需要設(shè)置服務(wù)端的地址和端口
   DatagramPacket pac = new DatagramPacket(new byte[0], 0, InetAddress.getByName("localhost"), 9191);
   
   // 掃描控制臺輸入
   Scanner scanner = new Scanner(System.in);
   scanner.useDelimiter("\r\n");
   String msg = null;
   while( !(msg = scanner.next()).equals("Bye") ){
    // 設(shè)置要發(fā)送的數(shù)據(jù)
    pac.setData(msg.getBytes()); 
    // 發(fā)送數(shù)據(jù)報
    client.send(pac);
    System.out.println("Sent Message --> " + msg);
   }
  }catch (IOException e){
   e.printStackTrace();
  }
  
 }
}

需要注意的是,UDP 是面向無連接的,但 DatagramSocket 的 API 中提供了帶有 connect 字樣的方法,這里的 connect 并非 TCP 中連接的意思。而是指定了當(dāng)前的 UDP 套接字只能夠向指定的主機和端口發(fā)送數(shù)據(jù)報。

以上就是Java 實現(xiàn)簡單Socket 通信的示例的詳細(xì)內(nèi)容,更多關(guān)于Java 實現(xiàn)Socket 通信的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Spring @Scheduler使用cron表達(dá)式時的執(zhí)行問題詳解

    Spring @Scheduler使用cron表達(dá)式時的執(zhí)行問題詳解

    Spring給程序猿們帶來了許多便利。下面這篇文章主要給大家介紹了關(guān)于Spring @Scheduler使用cron表達(dá)式時的執(zhí)行問題的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-09-09
  • myBatis組件教程之緩存的實現(xiàn)與使用

    myBatis組件教程之緩存的實現(xiàn)與使用

    這篇文章主要給大家介紹了關(guān)于myBatis組件教程之緩存的實現(xiàn)與使用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • Java使用策略模式解決商場促銷商品問題示例

    Java使用策略模式解決商場促銷商品問題示例

    這篇文章主要介紹了Java使用策略模式解決商場促銷商品問題,簡單描述了策略模式的概念、原理,并結(jié)合實例形式分析了Java基于策略模式解決商品促銷問題的相關(guān)操作技巧,需要的朋友可以參考下
    2018-05-05
  • idea運行tomcat報錯找不到catalina.bat,系統(tǒng)找不到指定的文件問題

    idea運行tomcat報錯找不到catalina.bat,系統(tǒng)找不到指定的文件問題

    這篇文章主要介紹了idea運行tomcat報錯找不到catalina.bat,系統(tǒng)找不到指定的文件問題,具有很好的參考價值,希望對大家有所幫助,
    2023-11-11
  • java實現(xiàn)6種字符串?dāng)?shù)組的排序(String array sort)

    java實現(xiàn)6種字符串?dāng)?shù)組的排序(String array sort)

    這篇文章主要介紹了java實現(xiàn)6種字符串?dāng)?shù)組的排序(String array sort),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • mybatis 遍歷foreach中or拼接的操作

    mybatis 遍歷foreach中or拼接的操作

    這篇文章主要介紹了mybatis 遍歷foreach中or拼接的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Java全面細(xì)致講解類與對象

    Java全面細(xì)致講解類與對象

    類和對象是兩種以計算機為載體的計算機語言的合稱。對象是對客觀事物的抽象,類是對對象的抽象。類是一種抽象的數(shù)據(jù)類型;變量就是可以變化的量,存儲在內(nèi)存中—個可以擁有在某個范圍內(nèi)的可變存儲區(qū)域
    2022-05-05
  • SpringSecurity多表多端賬戶登錄的實現(xiàn)

    SpringSecurity多表多端賬戶登錄的實現(xiàn)

    本文主要介紹了SpringSecurity多表多端賬戶登錄的實現(xiàn)
    2024-05-05
  • Springboot項目的搭建教程(分離出common父依賴)

    Springboot項目的搭建教程(分離出common父依賴)

    這篇文章主要介紹了Springboot項目的搭建教程(分離出common父依賴),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • SpringBoot整合mybatis簡單案例過程解析

    SpringBoot整合mybatis簡單案例過程解析

    這篇文章主要介紹了SpringBoot整合mybatis簡單案例過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11

最新評論

徐闻县| 双牌县| 贺州市| 民丰县| 海城市| 定边县| 班戈县| 玉山县| 城市| 枝江市| 万州区| 凭祥市| 泾源县| 巴彦县| 南靖县| 马尔康县| 香河县| 乌兰察布市| 景东| 陆良县| 永善县| 浦县| 淮北市| 瑞丽市| 怀来县| 临江市| 华蓥市| 威宁| 安阳县| 丰县| 永宁县| 随州市| 来凤县| 聂拉木县| 镇坪县| 靖宇县| 云梦县| 金平| 平泉县| 巩留县| 宁乡县|