Java socket第一次只发送数据

Java Socket sends data only for the first time

我正在制作客户端服务器应用程序。我启动服务器,然后启动客户端。当我单击 ClientGui class 中的任何按钮时,它会发送消息,但是当我再次单击任何其他按钮时,不会发送数据。我发送数据抛出以下代码行。

btn1.setOnAction(e->{
            dout.println("x1");
        });
btn2.setOnAction(e->{
            dout.println("x2");
        });

它们只为第一个 time.The 发送数据,随后是 ClientGui class 代码。

import java.io.PrintStream;
import java.io.DataInputStream;
import java.net.Socket;
import javafx.scene.control.Button;
import javafx.scene.layout.AnchorPane;
import javafx.scene.text.Font;
import javafx.application.Platform;

public class ClientGui extends AnchorPane {

    protected final Button btn1;
    protected final Button btn2;
    volatile String message = "";
    volatile String recievedMessage = "";
    static Socket s;
    static DataInputStream din;
    static PrintStream dout;

    public ClientGui() {
        btn1 = new Button();
        btn2 = new Button();
        
        try{
            s = new Socket("localhost", 5555);
            din = new DataInputStream(s.getInputStream());
            dout = new PrintStream(s.getOutputStream());
        }catch(Exception ex){}

        setId("AnchorPane");
        setPrefHeight(400.0);
        setPrefWidth(490.0);

        btn1.setAlignment(javafx.geometry.Pos.CENTER);
        btn1.setLayoutX(118.0);
        btn1.setLayoutY(86.0);
        btn1.setMnemonicParsing(false);
        btn1.setPrefHeight(48.0);
        btn1.setPrefWidth(75.0);
        btn1.setTextAlignment(javafx.scene.text.TextAlignment.CENTER);
        btn1.setFont(new Font(24.0));
        btn1.setOnAction(e->{
            dout.println("x1");
        });

        btn2.setAlignment(javafx.geometry.Pos.CENTER);
        btn2.setLayoutX(221.0);
        btn2.setLayoutY(86.0);
        btn2.setMnemonicParsing(false);
        btn2.setPrefHeight(48.0);
        btn2.setPrefWidth(75.0);
        btn2.setTextAlignment(javafx.scene.text.TextAlignment.CENTER);
        btn2.setFont(new Font(24.0));
        btn2.setOnAction(e->{
            dout.println("x2");
        });

        getChildren().add(btn1);
        getChildren().add(btn2);

        ClientHandler ch = new ClientHandler();
        ch.start();
    }
    
    class ClientHandler extends Thread{
        
        public void run(){
            while(true){
                
                try{
                    if(message.equals("stop"))
                        break;
                    recievedMessage = din.readLine();
                    playMove(recievedMessage);
                }catch(Exception ex){}
             
                try{
                    din.close();
                    dout.close();
                    s.close();
                }catch(Exception ex){}
            }
        }
        
    }
    
    public void playMove(String play){
        char position = play.charAt(1);
        System.out.println(position);
        Platform.runLater(new Runnable(){
            public void run(){
                switch(position){
                    case '1':
                        btn1.setText("x");
                        break;
                    case '2':
                        btn2.setText("x");
                        break;   
                    default:
                        break;
                }
            }
        });
    }
}

Gui 是 运行 在 class 中调用 ClientServerTic 这里是 class 代码。

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class ClientServerTic extends Application {

    @Override
    public void start(Stage stage){
        ClientGui root = new ClientGui();

        Scene scene = new Scene(root); 
        stage.setTitle("Tic Tac Toe");
        stage.setScene(scene);  
        stage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }

}

服务器侦听消息并将消息发送给所有客户端。这是服务器代码。

//package clientservertic;

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

public class Server{

  ServerSocket serverSocket;

  public Server() throws Exception{//constructor

    serverSocket = new ServerSocket(5555);

    while(true){

      Socket s = serverSocket.accept();
      new GameHandler(s);
    }

  }

  public static void main(String[] args) throws Exception{
    System.out.println("Server is listening!!!");
    new Server();
  }

}

class GameHandler extends Thread{

  DataInputStream dis;
  PrintStream ps;
  Socket s;
  static Vector<GameHandler> clientsVector = new Vector<GameHandler>();//array of chat threads

  public GameHandler(Socket clientSocket) throws Exception{//constructor

    dis = new DataInputStream(clientSocket.getInputStream());

    ps = new PrintStream(clientSocket.getOutputStream());

    s = clientSocket;

    clientsVector.add(this);
    start();//start the thread

  }

  public void run(){
    while(true){
      String str = "";
      try{
        str = dis.readLine();//get any new messages  

        if(str.trim().equals("STOP")){

          ps.close();
          dis.close();
          s.close();

        }else{

          sendMessageToAll(str);//send the message to all the clients

        }
      }catch(Exception ex){}

    }
  }

  public void sendMessageToAll(String str){
    //loop on all chat threads and send the message

    for(GameHandler ch : clientsVector){
      ch.ps.println(str);
    }
  }

}

在这个代码块中,您将在第一个循环之后的第二个 try catch 语句中关闭连接,这样您的循环就会短路

while(true){
                
                try{
                    if(message.equals("stop"))
                        break;
                    recievedMessage = din.readLine();
                    playMove(recievedMessage);
                }catch(Exception ex){}
             
                try{
                    din.close();
                    dout.close();
                    s.close();
                }catch(Exception ex){}
            }
        }

你应该做的是将第二个 try catch 放在 while 循环之后,它会正常工作。

while(true){

                try{
                    if(message.equals("stop"))
                        break;
                    System.out.println("before");
                    recievedMessage = din.readLine();
                    playMove(recievedMessage);
                }catch(Exception ex){}
}
            
try{
    din.close();
    dout.close();
    s.close();
}catch(Exception ex){}