91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么在JAVA項目中利用SOCKET實現一個多客戶端通信功能

發布時間:2020-12-01 14:51:48 來源:億速云 閱讀:210 作者:Leah 欄目:開發技術

怎么在JAVA項目中利用SOCKET實現一個多客戶端通信功能?相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

一、ServerSocket

1.為了方便調試,先創建一個界面用于顯示客戶端連接信息

怎么在JAVA項目中利用SOCKET實現一個多客戶端通信功能

基于javafx包寫的一個簡單界面!

 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(); //創建線程啟動Socket服務
  }

2.啟動Socket服務

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(); //程序會在這里阻塞,直到等到客戶端連接
     clientNumber++;
     /*
     這里就是在界面中輸出一些服務器、和連接的客戶端信息
      */
     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");
     });
     /*
     每有一個客戶端連接服務器就創建一個線程,進行通信處理
      */
     new Thread(new HandleServer(socket)).start();
     try{
      Thread.sleep(100); //多個客戶端連續快速連接服務器時,可能出現問題,這里設置延時
     }catch (InterruptedException e){
      e.printStackTrace();
     }
    }

   }catch (IOException e){
    e.printStackTrace();
   }
  }
 }

這一段代碼主要作用就是循環等待客戶端連接服務器:

Socket socket = serverSocket.accept();

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

然而并沒有看懂。。這個應該涉及到操作系統層面,等之后把操作系統搞明白了在來補充吧。

3.服務器處理類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 是一個自定義方法,serverTools.Tools()是一個工具類,一個靜態對象。
     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!");
   }

  }

這一塊的代碼主要就是創建輸入輸出數據流了

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

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

4.一些方法方便ServerTools類實現

  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.實現指定服務器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用于保存客戶端連接信息

一個粗糙的處理方式,邏輯上缺陷還很嚴重,主要我好像沒找到這樣的框架???

缺陷:因為服務器要返回客戶端的ID讓客戶端將ID顯示到交互界面,所以存在情況客戶端多次連接斷開后會使返回的ID出現重復

三、ClientSocket

1.同樣的先建一個簡單的界面用于輸出信息和顯示信息

怎么在JAVA項目中利用SOCKET實現一個多客戶端通信功能

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

第二個編輯框就是 輸入你要發送的信息了,很清楚

下面的就是顯示框,嗯!

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一個Socket 去連接服務器,socket(),括號里的就是服務器的IP,和程序的端口號了,這種基于tcp協議的好像都是一個樣???

2.創建一個線程用于循環獲取信息并顯示

 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);
   }

  }
 }

很簡單了,依舊是輸入輸出數據流,然后循環等待信息并輸出。

3.新建一個TestClient類 這個類 和ClientSocket 一模一樣 就是拿來測試的

怎么在JAVA項目中利用SOCKET實現一個多客戶端通信功能

四、總結

java寫socket 是真的簡單!!!^_ ^!

怎么在JAVA項目中利用SOCKET實現一個多客戶端通信功能

看完上述內容,你們掌握怎么在JAVA項目中利用SOCKET實現一個多客戶端通信功能的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

华安县| 弥渡县| 柘城县| 大石桥市| 尤溪县| 沅陵县| 乌拉特前旗| 金溪县| 如皋市| 高清| 襄城县| 云林县| 中牟县| 工布江达县| 兴安县| 同仁县| 本溪| 牡丹江市| 武鸣县| 图木舒克市| 景德镇市| 封开县| 眉山市| 北碚区| 且末县| 吴忠市| 毕节市| 贵阳市| 抚州市| 娱乐| 都匀市| 安吉县| 科尔| 宜昌市| 崇礼县| 永州市| 普兰店市| 拜城县| 土默特左旗| 阿图什市| 梧州市|