国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

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

瀏覽:4日期:2022-08-15 17:52:24

Java socket 封裝了傳輸層的實現(xiàn)細節(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 通過序列號、確認應(yīng)答、數(shù)據(jù)校驗等機制確保了傳輸?shù)目煽啃裕m用于需要可靠數(shù)據(jù)傳輸?shù)膱鼍埃瑧?yīng)用層協(xié)議 HTTP,F(xiàn)TP 基于 TCP。UDP 沒有復雜的控制機制,不糾錯,不重發(fā),不保證數(shù)據(jù)的準確性,不確保數(shù)據(jù)到達目的地;不過 UDP 傳送等量數(shù)據(jù)花費更小的流量,適用于對時延要求高但對準確性要求不高的場景,如視頻、音頻通訊。

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.javaBind Port 9090New client connected.Received Message --> Are you OK!

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

$ java Client.javaAre 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 %dn', 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('rn'); 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)了與上面程序同樣的功能。不過消息可能會出錯,某些消息可能也不能到達服務(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ù)報,這個實例可以重復利用。 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('rn'); 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 中連接的意思。而是指定了當前的 UDP 套接字只能夠向指定的主機和端口發(fā)送數(shù)據(jù)報。

以上就是Java 實現(xiàn)簡單Socket 通信的示例的詳細內(nèi)容,更多關(guān)于Java 實現(xiàn)Socket 通信的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: Java
相關(guān)文章:
主站蜘蛛池模板: 美国一级毛片完整高清 | 免费观看黄色毛片 | 免费观看性欧美一级 | 岛国大片在线播放免费 | 成人毛片免费播放 | 国产成年人网站 | 久久久综合网 | 欧美日韩精品高清一区二区 | 午夜精品尤物福利视频在线 | 草草影院www色欧美极品 | 久久视频6免费观看视频精品 | 免费一级欧美大片在线观看 | 日韩欧美不卡一区二区三区 | 久久亚洲欧洲日产国码 | 女人张开腿让男人桶免费最新 | 无套内谢孕妇毛片免费看 | 一区二区三区欧美日韩国产 | 国产大臿蕉香蕉大视频 | 毛片免费观看的视频 | 亚洲国产影院 | 在线 | 一区二区三区四区 | 狠狠色婷婷丁香综合久久韩国 | 久久骚| 中文字幕亚洲区 | 国产欧美一区二区精品久久久 | 国产乱码精品一区二区三区卡 | 小明日韩在线看看永久区域 | 久久久一本 | 欧美亚洲中日韩中文字幕在线 | 伊人青 | 欧美jlzz18性欧美 | 久久久久久久久中文字幕 | 国产成人精品999在线观看 | 国产日韩欧美在线一二三四 | 手机亚洲第1页 | 亚洲伊人色综合网站亚洲伊人 | 艹美女视频 | 国产日韩一区二区三区 | 深夜福利视频在线观看免费播放 | 午夜国产片 | 黄a网站|