日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

java實現基于UDP協議網絡Socket編程(C/S通信)

瀏覽:27日期:2022-08-21 17:46:32

一、前言:認識UDP

UDP,全稱User Datagram Protocol(用戶數據報協議),是Internet 協議集支持一個無連接的傳輸協議。UDP 為應用程序提供了一種無需建立連接就可以發送封裝的 IP 數據包的方法。

UDP主要用于不要求分組順序到達的傳輸中,分組傳輸順序的檢查與排序由應用層完成,提供面向報文的簡單不可靠信息傳送服務。UDP 協議基本上是IP協議與上層協議的接口,適用端口分別運行在同一臺設備上的多個應用程序。

二、UDP的特點(與TCP相比)

正是UDP提供不可靠服務,具有了TCP所沒有的優勢。無連接使得它具有資源消耗小,處理速度快的優點,所以音頻、視頻和普通數據在傳送時經常使用UDP,偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。

UDP有別于TCP,有自己獨立的套接字(IP+Port),它們的端口號不沖突。和TCP編程相比,UDP在使用前不需要進行連接,沒有流的概念。

如果說TCP協議通信與電話通信類似,那么UDP通信就與郵件通信類似:不需要實時連接,只需要目的地址;

UDP通信前不需要建立連接,只要知道地址(ip地址和端口號)就可以給對方發送信息;

基于用戶數據報文(包)讀寫;

UDP通信一般用于線路質量好的環境,如局域網內,如果是互聯網,往往應用于對數據完整性不是過于苛刻的場合,例如語音傳送等。

以上是對UDP的基本認識,與以前學習的理論相比,接下來的實踐更加有趣,實踐出真知。

三、UDP網絡Socket編程(Java實現)

首先,熟悉java中UDP編程的幾個關鍵類:DatagramSocket(套接字類),DatagramPacket(數據報類),MulticastSocket。本篇主要使用前兩個。

1、創建客戶端

第一步,實例化一個數據報套接字,用于與服務器端進行通信。與TCP不同,UDP中只有DatagramSocket一種套接字,不區分服務端和客戶端,創建的時候并不需要指定目的地址,這也是TCP協議和UDP協議最大的不同點之一。

public UDPClient(String remoteIP,String remotePort) throws IOException{ this.remoteIP=InetAddress.getByName(remoteIP); this.remotePort=Integer.parseInt(remotePort); //創建UDP套接字,系統隨機選定一個未使用的UDP端口綁定 socket=new DatagramSocket();}

第二步, 創建UDP數據報,實現發送和接收數據的方法。UDP發送數據是基于報文DatagramPacket,網絡中傳遞的UDP數據都要封裝在這種自包含的報文中。

實現DatagramPacket發送數據的方法:

//定義一個數據的發送方法public void send(String msg){ try { //將待發送的字符串轉為字節數組 byte[] outData=msg.getBytes('utf-8'); //構建用于發送的數據報文,構造方法中傳入遠程通信方(服務器)的ip地址和端口 DatagramPacket outPacket=new DatagramPacket(outData,outData.length,remoteIP,remotePort); //給UDP發送數據報 socket.send(outPacket); }catch (IOException e){ e.printStackTrace(); }}

DatagramPacket接收數據的方法:

//定義一個數據的發送方法public void send(String msg){ try { //將待發送的字符串轉為字節數組 byte[] outData=msg.getBytes('utf-8'); //構建用于發送的數據報文,構造方法中傳入遠程通信方(服務器)的ip地址和端口 DatagramPacket outPacket=new DatagramPacket(outData,outData.length,remoteIP,remotePort); //給UDP發送數據報 socket.send(outPacket); }catch (IOException e){ e.printStackTrace(); }}

可以看到,發送和接收數據中使用DatagramSocket的實例的send和receive方法,這就是數據報套接字的兩個重要方法。

通信結束,銷毀Socket的方法如下:

public void close(){ if (socket!=null) socket.close();}

到這里,客戶端已全部完成,等待接下來與服務端的通信...

2、客戶端圖形界面

現在,設計客戶端通信的簡單界面,一方面可以更方便的和服務器連續對話通信,另一方面,有了圖形界面,體驗感更加!圖形化界面主要使用JavaFX實現,代碼容易看懂。

import javafx.application.Application;import javafx.event.EventHandler;import javafx.geometry.Insets;import javafx.geometry.Pos;import javafx.scene.Scene;import javafx.scene.control.*;import javafx.scene.input.KeyCode;import javafx.scene.input.KeyEvent;import javafx.scene.layout.BorderPane;import javafx.scene.layout.HBox;import javafx.scene.layout.Priority;import javafx.scene.layout.VBox;import javafx.stage.Stage;import java.io.IOException;public class UDPClientFX extends Application { private Button btnExit=new Button('退出'); private Button btnSend = new Button('發送'); private TextField tfSend=new TextField();//輸入信息區域 private TextArea taDisplay=new TextArea();//顯示區域 private TextField ipAddress=new TextField();//填寫ip地址 private TextField tfport=new TextField();//填寫端口 private Button btConn=new Button('連接'); private UDPClient UDPClient; private String ip; private String port; @Override public void start(Stage primaryStage) { BorderPane mainPane=new BorderPane(); //連接服務器區域 HBox hBox1=new HBox(); hBox1.setSpacing(10); hBox1.setPadding(new Insets(10,20,10,20)); hBox1.setAlignment(Pos.CENTER); hBox1.getChildren().addAll(new Label('ip地址:'),ipAddress,new Label('端口:'),tfport,btConn); mainPane.setTop(hBox1); VBox vBox=new VBox(); vBox.setSpacing(10); vBox.setPadding(new Insets(10,20,10,20)); vBox.getChildren().addAll(new Label('信息顯示區'),taDisplay,new Label('信息輸入區'),tfSend); VBox.setVgrow(taDisplay, Priority.ALWAYS); mainPane.setCenter(vBox); HBox hBox=new HBox(); hBox.setSpacing(10); hBox.setPadding(new Insets(10,20,10,20)); hBox.setAlignment(Pos.CENTER_RIGHT); hBox.getChildren().addAll(btnSend,btnExit); mainPane.setBottom(hBox); Scene scene =new Scene(mainPane,700,500); primaryStage.setScene(scene); primaryStage.show(); //連接服務器之前,發送bye后禁用發送按鈕,禁用Enter發送信息輸入區域,禁用下載按鈕 btnSend.setDisable(true); tfSend.setDisable(true); //連接按鈕 btConn.setOnAction(event -> { ip=ipAddress.getText().trim(); port=tfport.getText().trim(); try {UDPClient = new UDPClient(ip,port);//連接服務器之后未結束服務前禁用再次連接btConn.setDisable(true);//重新連接服務器時啟用輸入發送功能tfSend.setDisable(false);btnSend.setDisable(false); } catch (IOException e) {e.printStackTrace(); } }); //發送按鈕事件 btnSend.setOnAction(event -> { String msg=tfSend.getText(); UDPClient.send(msg);//向服務器發送一串字符 taDisplay.appendText('客戶端發送:'+msg+'n'); String Rmsg=null; Rmsg=UDPClient.receive();// System.out.println(Rmsg); taDisplay.appendText(Rmsg+'n'); if (msg.equals('bye')){btnSend.setDisable(true);//發送bye后禁用發送按鈕tfSend.setDisable(true);//禁用Enter發送信息輸入區域//結束服務后再次啟用連接按鈕btConn.setDisable(false); } tfSend.clear(); }); //對輸入區域綁定鍵盤事件 tfSend.setOnKeyPressed(new EventHandler<KeyEvent>() { @Override public void handle(KeyEvent event) {if(event.getCode()==KeyCode.ENTER){ String msg=tfSend.getText(); UDPClient.send(msg);//向服務器發送一串字符 taDisplay.appendText('客戶端發送:'+msg+'n'); String Rmsg=null; Rmsg=UDPClient.receive(); taDisplay.appendText(Rmsg+'n'); if (msg.equals('bye')){ tfSend.setDisable(true);//禁用Enter發送信息輸入區域 btnSend.setDisable(true);//發送bye后禁用發送按鈕 //結束服務后再次啟用連接按鈕 btConn.setDisable(false); } tfSend.clear();} } });btnExit.setOnAction(event -> { try {exit(); } catch (InterruptedException e) {e.printStackTrace(); } }); //窗體關閉響應的事件,點擊右上角的×關閉,客戶端也關閉 primaryStage.setOnCloseRequest(event -> { try {exit(); } catch (InterruptedException e) {e.printStackTrace(); } }); //信息顯示區鼠標拖動高亮文字直接復制到信息輸入框,方便選擇文件名 //taDispaly為信息選擇區的TextArea,tfSend為信息輸入區的TextField //為taDisplay的選擇范圍屬性添加監聽器,當該屬性值變化(選擇文字時),會觸發監聽器中的代碼 taDisplay.selectionProperty().addListener(((observable, oldValue, newValue) -> { //只有當鼠標拖動選中了文字才復制內容 if(!taDisplay.getSelectedText().equals(''))tfSend.setText(taDisplay.getSelectedText()); })); } private void exit() throws InterruptedException { if (UDPClient!=null){ //向服務器發送關閉連接的約定信息 UDPClient.send('bye'); UDPClient.close(); } System.exit(0); } public static void main (String[] args) { launch(args); }}

重點在各個控件的事件處理邏輯上,需避免要一些誤操作導致異常拋出,如:連接服務器前禁用發送按鈕,在連接服務器成功后禁用連接按鈕,禁用輸入區等。另外,實現了回車發送的快捷功能,詳見代碼的鍵盤事件綁定部分。

還有,約定發送'bye'或者退出按鈕結束通信關閉Socket。

java實現基于UDP協議網絡Socket編程(C/S通信)

成功連接后:

java實現基于UDP協議網絡Socket編程(C/S通信)

3、創建服務器端

服務器端為客戶端提供服務,實現通信。這里包括了幾個方法Service(),udpSend()和udpReceive().

首先,我將UDP數據報發送和接收寫成一個方法,作為整體方便多次調用。

public DatagramPacket udpReceive() throws IOException { DatagramPacket receive; byte[] dataR = new byte[1024]; receive = new DatagramPacket(dataR, dataR.length); socket.receive(receive); return receive;}public void udpSend(String msg,InetAddress ipRemote,int portRemote) throws IOException { DatagramPacket sendPacket; byte[] dataSend = msg.getBytes(); sendPacket = new DatagramPacket(dataSend,dataSend.length,ipRemote,portRemote); socket.send(sendPacket);}

與TCP的Socket通信不同,需要將數據轉化成字節數據形式,封裝成數據報進行傳輸,接收時解析數據為字節,再進行讀取。

服務器端核心部分為Service()方法,實例化一個DatagramSocket類套接字,實現循環與客戶端的通信。

與客戶端約定的結束標志'bye'進行處理,結束對話。

public DatagramPacket udpReceive() throws IOException { DatagramPacket receive; byte[] dataR = new byte[1024]; receive = new DatagramPacket(dataR, dataR.length); socket.receive(receive); return receive;}public void udpSend(String msg,InetAddress ipRemote,int portRemote) throws IOException { DatagramPacket sendPacket; byte[] dataSend = msg.getBytes(); sendPacket = new DatagramPacket(dataSend,dataSend.length,ipRemote,portRemote); socket.send(sendPacket);}

四、服務器端和客戶端完整代碼

服務器端:

public DatagramPacket udpReceive() throws IOException { DatagramPacket receive; byte[] dataR = new byte[1024]; receive = new DatagramPacket(dataR, dataR.length); socket.receive(receive); return receive;}public void udpSend(String msg,InetAddress ipRemote,int portRemote) throws IOException { DatagramPacket sendPacket; byte[] dataSend = msg.getBytes(); sendPacket = new DatagramPacket(dataSend,dataSend.length,ipRemote,portRemote); socket.send(sendPacket);}

客戶端:

//UDPClient.javaimport java.io.IOException;import java.net.DatagramPacket;import java.net.DatagramSocket;import java.net.InetAddress;public class UDPClient { private int remotePort; private InetAddress remoteIP; private DatagramSocket socket; //用于接收數據的報文字節數組緩存最最大容量,字節為單位 private static final int MAX_PACKET_SIZE=512; public UDPClient(String remoteIP,String remotePort) throws IOException{ this.remoteIP=InetAddress.getByName(remoteIP); this.remotePort=Integer.parseInt(remotePort); //創建UDP套接字,系統隨機選定一個未使用的UDP端口綁定 socket=new DatagramSocket(); } //定義一個數據的發送方法 public void send(String msg){ try { //將待發送的字符串轉為字節數組 byte[] outData=msg.getBytes('utf-8'); //構建用于發送的數據報文,構造方法中傳入遠程通信方(服務器)的ip地址和端口 DatagramPacket outPacket=new DatagramPacket(outData,outData.length,remoteIP,remotePort); //給UDP發送數據報 socket.send(outPacket); }catch (IOException e){ e.printStackTrace(); } } public String receive(){ String msg; //準備空的數據報文 DatagramPacket inPacket=new DatagramPacket(new byte[MAX_PACKET_SIZE],MAX_PACKET_SIZE); try { //讀取報文,阻塞語句,有數據就裝包在inPacket報文中,以裝完或裝滿為止 socket.receive(inPacket); //將接收到的字節數組轉為對應的字符串 msg=new String(inPacket.getData(),0,inPacket.getLength(),'utf-8'); } catch (IOException e) { e.printStackTrace(); msg=null; } return msg; } public void close(){ if (socket!=null) socket.close(); }}

五、效果展示

java實現基于UDP協議網絡Socket編程(C/S通信)

六、總結

這一篇詳細記錄學習運用java進行網絡編程,基于UDP套接字(Socket)實現服務器與客戶端間的通信,在實戰案例中更深刻理解UDP的實現原理,掌握UDP實踐應用步驟。

起初完成UDP通信時,遇到了幾個問題,相比較TCP的實現,確實體會到數據傳輸的過程的不同,UDP服務和客戶端共用了一個DatagramSocket,另外需要DatagramPacket數據報的協作。另外,UDP沒有數據流的概念,所以讀寫不同于TCP,需要以字節數據進行讀取。

到此這篇關于java實現基于UDP協議網絡Socket編程(C/S通信)的文章就介紹到這了,更多相關java UDP協議Socket編程內容請搜索好吧啦網以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持好吧啦網!

標簽: Java
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产乱码精品一区二区亚洲| 欧美精品日日操| 91一区二区| 麻豆91小视频| 国产精品免费不| 欧美一级二级三级视频| 欧美精品一二| 久久激情中文| 日韩在线观看| 91精品一区二区三区综合| 天堂√中文最新版在线| 国产传媒av在线| 日韩在线欧美| 99国产精品一区二区| 自由日本语亚洲人高潮| 香蕉久久久久久久av网站| 精品一区欧美| 日韩中文字幕亚洲一区二区va在线| 国产韩日影视精品| 久久国产精品99国产| 91亚洲无吗| 国产精品视频一区二区三区| 国产精品.xx视频.xxtv| 精品久久99| 国产综合欧美| 欧美偷窥清纯综合图区| 精品99在线| 性色av一区二区怡红| 欧美一区二区三区久久精品| 91av亚洲| 日韩高清电影免费| 久久亚洲国产精品尤物| 婷婷激情图片久久| 国产亚洲电影| 久久在线电影| 69堂免费精品视频在线播放| 国产精品一区二区三区四区在线观看| 麻豆视频在线观看免费网站黄 | 欧美一区二区性| 欧美日韩网址| 一区二区亚洲精品| 福利一区二区三区视频在线观看| 亚洲深夜av| 韩国女主播一区二区三区| 午夜在线精品偷拍| 日韩在线二区| 综合激情视频| av不卡免费看| 日韩天堂在线| 精品一区二区三区免费看| 美日韩精品视频| 中文字幕一区久| 欧美国产日本| 国产亚洲久久| 亚洲三级在线| 免费欧美日韩| 午夜久久99| 色综合www| 麻豆视频观看网址久久| 青青国产精品| 欧美日韩一区二区三区四区在线观看 | 日欧美一区二区| 黄色日韩在线| 国产91精品对白在线播放| 国产aⅴ精品一区二区四区| 久久不卡国产精品一区二区| 亚洲精品综合| 69堂精品视频在线播放| 日本特黄久久久高潮| 欧美午夜不卡| 一区二区精品| 亚洲一区二区三区久久久| 中文一区一区三区免费在线观| 午夜久久黄色| 亚洲精品第一| 日本va欧美va精品| 国产欧美二区| 欧美精品日日操| 久久国产亚洲精品| av一区二区高清| 一区三区视频| 日韩午夜视频在线| 国产精品久久久久久模特| 久久久久久色 | 日韩国产欧美一区二区三区| 国产精品chinese| 四季av一区二区凹凸精品| 亚洲最新无码中文字幕久久| 欧美一区二区三区高清视频| 99视频精品| 欧美国产日韩电影| av综合电影网站| 在线精品亚洲| 高清久久一区| 亚洲欧美日韩一区在线观看| 777久久精品| 日韩国产一区二区三区| 午夜在线精品偷拍| 日韩三区四区| 成人在线网站| 国产精品一卡| 视频在线在亚洲| 国产激情久久| 在线视频精品| 精品一二三区| 亚洲一区二区三区中文字幕在线观看| 国产成年精品| 青草av.久久免费一区| 久久婷婷av| 麻豆成人在线观看| 亚洲精品动态| 好吊日精品视频| 精品一区二区三区四区五区| 黄色日韩在线| 久久久久美女| 国产精品久久免费视频| 石原莉奈一区二区三区在线观看| 丁香婷婷久久| 久久婷婷国产| 精品视频久久| 国产精品久久国产愉拍| 日韩中文字幕一区二区三区| 91久久午夜| 超碰99在线| 久久精品国产福利| 国产精品一区二区免费福利视频| 日本一区二区三区视频在线看 | 日本精品在线播放| 国产精品普通话对白| 黄色成人91| 99精品视频在线| 国内一区二区三区| 久久精品日韩欧美| 久久精品网址| 国产精品亚洲欧美| 久久av电影| 激情综合五月| 久久蜜桃资源一区二区老牛| 99视频精品全部免费在线视频| 99精品在线| 久久中文字幕二区| 99视频一区| 国产精品亲子伦av一区二区三区 | 精品国产成人| 在线观看精品| 蜜臀久久99精品久久一区二区| 欧美日韩亚洲在线观看| 日韩视频中文| 97久久精品| 国产一区二区色噜噜| 91精品成人| 日韩在线网址| 日本成人中文字幕| 精品国产不卡一区二区| 91精品亚洲| 久久亚洲视频| 麻豆免费精品视频| 欧美精品一区二区久久| 亚洲深夜福利在线观看| 欧美日韩1区| 日韩综合在线| 日韩国产91| 亚洲大全视频| 国产精品扒开腿做爽爽爽软件| 欧美日韩尤物久久| 日韩三级精品| 亚洲成人三区| 日韩av不卡在线观看| 久久精品伊人| 野花国产精品入口| 国产精品videossex| 黄色成人精品网站| 美女在线视频一区| 亚洲欧美日韩一区在线观看| 狠狠久久伊人| 欧美在线观看天堂一区二区三区| 99久久亚洲精品蜜臀| 精品久久一区| 国产日韩一区二区三免费高清| 欧美性感美女一区二区| 久久字幕精品一区| 日韩精品久久理论片| 婷婷激情一区| 国产福利亚洲| 欧美欧美黄在线二区| 亚洲尤物av| 中文不卡在线| 99久久久久国产精品| 国产videos久久| 国产精品免费精品自在线观看| 亚洲a级精品| 国产毛片一区| 国产视频一区三区| 免费观看不卡av| 中文字幕人成乱码在线观看 | 日韩大片在线| 精品视频久久| 不卡专区在线| 日韩精品网站| 99视频精品全国免费|