亚洲免费在线视频-亚洲啊v-久久免费精品视频-国产精品va-看片地址-成人在线视频网

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

JAVA實(shí)現(xiàn)SOCKET多客戶端通信的案例

瀏覽:4日期:2022-08-20 10:32:52

一、ServerSocket

1.為了方便調(diào)試,先創(chuàng)建一個(gè)界面用于顯示客戶端連接信息

JAVA實(shí)現(xiàn)SOCKET多客戶端通信的案例

基于javafx包寫(xiě)的一個(gè)簡(jiǎn)單界面!

javafx.scene.control.TextArea ta = new javafx.scene.control.TextArea(); @Override public void start(Stage primaryStage) throws Exception { scene = new Scene(ta,450,200); primaryStage.setTitle('SocketServer'); primaryStage.setScene(scene); primaryStage.show(); pStage = primaryStage; new Thread(new MyServer()).start(); //創(chuàng)建線程啟動(dòng)Socket服務(wù) }

2.啟動(dòng)Socket服務(wù)

public class MyServer implements Runnable{ @Override public void run() { try{ java.net.ServerSocket serverSocket = new java.net.ServerSocket(8000); ta.appendText('Server started at ' + new Date()+'n'); while(true){ Socket socket = serverSocket.accept(); //程序會(huì)在這里阻塞,直到等到客戶端連接 clientNumber++; /* 這里就是在界面中輸出一些服務(wù)器、和連接的客戶端信息 */ Platform.runLater(()->{ ta.appendText('Starting thread for client ' + clientNumber + ' at ' +new Date() +'n'); InetAddress inetAddress = socket.getInetAddress(); ta.appendText('Client '+clientNumber + '’s host name is' +inetAddress.getHostName() +'n'); ta.appendText('Client'+clientNumber + '’s IP address is '+ inetAddress.getHostAddress()+'n'); }); /* 每有一個(gè)客戶端連接服務(wù)器就創(chuàng)建一個(gè)線程,進(jìn)行通信處理 */ new Thread(new HandleServer(socket)).start(); try{ Thread.sleep(100); //多個(gè)客戶端連續(xù)快速連接服務(wù)器時(shí),可能出現(xiàn)問(wèn)題,這里設(shè)置延時(shí) }catch (InterruptedException e){ e.printStackTrace(); } } }catch (IOException e){ e.printStackTrace(); } } }

這一段代碼主要作用就是循環(huán)等待客戶端連接服務(wù)器:

Socket socket = serverSocket.accept();

在寫(xiě)這篇博客時(shí),突然想知道阻塞的原理就去查了一下。。。。

然而并沒(méi)有看懂。。這個(gè)應(yīng)該涉及到操作系統(tǒng)層面,等之后把操作系統(tǒng)搞明白了在來(lái)補(bǔ)充吧。

3.服務(wù)器處理類HandleServer

class HandleServer implements Runnable { private Socket socket; private int name; private int toClientID; private DataOutputStream outputStream; private DataInputStream inputStream; public HandleServer(Socket socket){ this.socket = socket; ServerTools.Tools().add(this); this.name = clientNumber; } @Override public void run() { try{ inputStream = new DataInputStream(socket.getInputStream()); outputStream = new DataOutputStream(socket.getOutputStream()); outputStream.writeUTF('Your ID is:'+clientNumber); while (true){ toClientID = inputStream.readInt(); String messageGET = inputStream.readUTF(); int err = ServerTools.Tools().MyWriteUTF(messageGET,toClientID); //MyWriteUTF 是一個(gè)自定義方法,serverTools.Tools()是一個(gè)工具類,一個(gè)靜態(tài)對(duì)象。 if (err==0){ outputStream.writeUTF('No have this ID!'); } Platform.runLater(()->{ ta.appendText(socket.getInetAddress().getHostName()+' Message received from client:' + messageGET +'n' ); }); System.out.println(clientNumber); } }catch (IOException e){ clientNumber--; System.out.println(clientNumber); System.err.println('Client is closed!'); } }

這一塊的代碼主要就是創(chuàng)建輸入輸出數(shù)據(jù)流了

inputStream = new DataInputStream(socket.getInputStream());

outputStream = new DataOutputStream(socket.getOutputStream());

4.一些方法方便ServerTools類實(shí)現(xiàn)

public void MyWriteUTF(String message){ try { outputStream.writeUTF(message); } catch (IOException e) { ServerTools.Tools().remove(this); e.printStackTrace(); } } public int getName() { return name; }

二、ServerTools

1.實(shí)現(xiàn)指定服務(wù)器ID輸出信息的工具

public class ServerTools { private static final ServerTools servertools = new ServerTools(); public static ServerTools Tools(){ return servertools; } Vector<MyServerSocket.HandleServer> vector = new Vector<MyServerSocket.HandleServer>(); public void add(MyServerSocket.HandleServer cs){ vector.add(cs); } public void remove(MyServerSocket.HandleServer cs){ vector.remove(cs); } public int MyWriteUTF(String message,int target) { for (int i = 0; i <= target; i++){ try { if (vector.get(i).getName() == target) { MyServerSocket.HandleServer MSSHC = vector.get(i); MSSHC.MyWriteUTF(message); return 1; } }catch (ArrayIndexOutOfBoundsException e){ e.printStackTrace(); return 0; } } return 0; }}

vector用于保存客戶端連接信息

一個(gè)粗糙的處理方式,邏輯上缺陷還很嚴(yán)重,主要我好像沒(méi)找到這樣的框架???

缺陷:因?yàn)榉?wù)器要返回客戶端的ID讓客戶端將ID顯示到交互界面,所以存在情況客戶端多次連接斷開(kāi)后會(huì)使返回的ID出現(xiàn)重復(fù)

三、ClientSocket

1.同樣的先建一個(gè)簡(jiǎn)單的界面用于輸出信息和顯示信息

JAVA實(shí)現(xiàn)SOCKET多客戶端通信的案例

第一個(gè)編輯框就是 輸入要發(fā)送指定客戶端的ID 例如:1 或 2 這樣的???

第二個(gè)編輯框就是 輸入你要發(fā)送的信息了,很清楚

下面的就是顯示框,嗯!

public class MyClientSocket extends Application { private Socket socket; private DataOutputStream toServer = null; private DataInputStream fromServer = null; private String ID; private int targetID = 0; private TextArea ta; @Override public void start(Stage primaryStage) throws Exception { BorderPane paneForTextField = new BorderPane(); paneForTextField.setPadding(new Insets(5,5,5,5)); paneForTextField.setStyle('-fx-border-color: green'); paneForTextField.setLeft(new Label('Enter a Message:')); TextField tf = new TextField(); tf.setAlignment(Pos.BOTTOM_RIGHT); paneForTextField.setCenter(tf); BorderPane ID_lable = new BorderPane(); ID_lable.setPadding(new Insets(5,5,5,5)); ID_lable.setStyle('-fx-border-color: green'); ID_lable.setLeft(new Label('Enter a ID for send message:')); TextField getId = new TextField(); getId.setAlignment(Pos.BOTTOM_RIGHT); ID_lable.setCenter(getId); paneForTextField.setTop(ID_lable); BorderPane mainPane = new BorderPane(); ta = new TextArea(); mainPane.setCenter(new ScrollPane(ta)); mainPane.setTop(paneForTextField); Scene scene = new Scene(mainPane,450,200); primaryStage.setTitle('SocketClient'); primaryStage.setScene(scene); primaryStage.show(); tf.setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { targetID = Integer.parseInt(getId.getText().trim()); if (targetID > 0 || targetID!=Integer.parseInt(ID)); else return; try { String putMessage = tf.getText().trim(); toServer.writeInt(targetID); toServer.writeUTF(putMessage); toServer.flush(); ta.appendText('PUT message is :'+ putMessage +'n'); tf.setText(''); }catch (IOException ex ){ System.err.println(ex); } } }); try{ socket = new Socket('localhost',8000); fromServer = new DataInputStream(socket.getInputStream()); toServer = new DataOutputStream(socket.getOutputStream()); ID = fromServer.readUTF(); paneForTextField.setRight(new Label('Your ID is:'+ID)); new Thread(new getMessage(socket,fromServer)).start(); }catch (IOException ex){ ta.appendText(ex.toString() +'n'); } }}

一樣的要new一個(gè)Socket 去連接服務(wù)器,socket(),括號(hào)里的就是服務(wù)器的IP,和程序的端口號(hào)了,這種基于tcp協(xié)議的好像都是一個(gè)樣???

2.創(chuàng)建一個(gè)線程用于循環(huán)獲取信息并顯示

class getMessage implements Runnable{ private Socket socket; private DataInputStream formServer; public getMessage(Socket socket,DataInputStream formServer){ this.socket = socket; this.formServer = formServer; } @Override public void run() { try { while (true) { String Message = formServer.readUTF(); try{ Thread.sleep(100); }catch (InterruptedException e) { e.printStackTrace(); } ta.appendText('GET message from server is:' + Message + 'n'); } }catch (IOException e){ System.err.println(e); } } }

很簡(jiǎn)單了,依舊是輸入輸出數(shù)據(jù)流,然后循環(huán)等待信息并輸出。

3.新建一個(gè)TestClient類 這個(gè)類 和ClientSocket 一模一樣 就是拿來(lái)測(cè)試的

JAVA實(shí)現(xiàn)SOCKET多客戶端通信的案例

四、總結(jié)

java寫(xiě)socket 是真的簡(jiǎn)單!!!^_ ^!

JAVA實(shí)現(xiàn)SOCKET多客戶端通信的案例

以上這篇JAVA實(shí)現(xiàn)SOCKET多客戶端通信的案例就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 成年人网站在线 | va欧美 | 日本精品高清一区二区不卡 | 亚洲国产网站 | 伊人青| 一级毛片区 | 国产亚洲一区二区三区在线 | 一级黄色香蕉视频 | 99精品在线 | 老司机一级片 | 久久网免费| 日本免费一区二区三区看片 | 国产欧美日本 | 色老头老太做爰视频在线观看 | 亚洲涩涩精品专区 | 99久久精品免费观看国产 | 欧美日韩一 | 国产三级做爰在线观看视频 | 一级aaaaaa毛片免费同男同女 | 蕾丝视频永久在线入口香蕉 | 免费观看一级成人毛片 | 一级黄片毛片 | 国产欧美在线观看 | 国产成人精品日本亚洲麻豆 | 久久久久久久99久久久毒国产 | 男人天堂亚洲 | 国产小呦 | 国产成人丝袜网站在线看 | 大尺度福利视频在线观看网址 | 国产a久久精品一区二区三区 | 男女同床爽爽视频免费 | 国产一级毛片国产 | 日韩加勒比 | 日韩不卡在线 | 欧美日韩偷拍自拍 | 亚洲综合视频 | 一区二区三区四区免费视频 | 九九久久视频 | 亚洲精品一区二区手机在线 | 在线视频亚洲 | 欧美一级aa免费毛片 |