2016-03-02 57 views
1

我当前在使用套接字编写客户端服务器时出现了一些问题,我希望同时连接多个客户端。 问题是,我有一个客户端 - 图形用户界面,我想改变一个圆的颜色,每当服务器发送信号这样做。在客户端 - 服务器应用程序中更改圆的颜色

我在客户端窗口中使用了JavaFX。

我遇到的问题是服务器通过连接运行(使用线程)并在完成后对所有的更改进行了修改,而我希望能够动态完成。

这是我的clientserver-thread-code。它将参数发送到客户端拾取的套接字,并相应地显示颜色,然后在改变另一个圆的颜色之前休眠一段固定的时间。我也有一个服务器类,它使用给定的端口号启动服务器,并持续监听客户端。

class ClientServer extends Thread 
{ 
Socket connectSocket; 
InetAddress clientAddr; 
String parametersFromClient; 
char[] params; 


public ClientServer(Socket connectSocket) 
{ 
    this.connectSocket = connectSocket; 
    clientAddr = connectSocket.getInetAddress(); 
} 

public void run() 
{ 
    try (

      //writer to the connection socket 
      PrintWriter output = new PrintWriter(connectSocket.getOutputStream(), true); 

      // Stream reader from the connection socket 
      BufferedReader input = new BufferedReader(new InputStreamReader(connectSocket.getInputStream())); 
    ) 
    { 
      int[] lights = MultipleClientsServer.lightvalues; 
     while (((parametersFromClient = input.readLine()) != null)) //FIKS!!! 
     { 
      if(parametersFromClient.equals("connect")) 
      { 
      System.out.println(parametersFromClient); 
      output.println("red"); 
      try {TimeUnit.SECONDS.sleep(lights[0]);} catch (InterruptedException e) {} 

      output.println("yellow"); 
      try {TimeUnit.SECONDS.sleep(lights[1]);} catch (InterruptedException e) {} 

      output.println("green"); 
      try {TimeUnit.SECONDS.sleep(lights[2]);} catch (InterruptedException e) {} 

      output.println(""); 
      } 
     } 

     System.out.println(MultipleClientsServer.IPList.toString()); 
     MultipleClientsServer.removeFromList(clientAddr.toString()); 
     // close the connection socket 
     connectSocket.close(); 
     //søke etter inetadress i linkedlist for å fjerne 
     System.out.println(MultipleClientsServer.IPList.toString()); 


    } catch (IOException e) 
    { 
     System.out.println("Exception occurred when trying to communicate with the client " + clientAddr.getHostAddress()); 
     System.out.println(e.getMessage()); 
    } 
} 

在我的客户端代码,我有一个连接的方法,它启动时,我按下一个按钮:(红,黄,绿是我想改变颜色的圆圈)

public static Socket clientStart() 
{ 
    String hostName = "127.0.0.1"; // Default host, localhost 
    int portNumber = 5555; // Default port to use 

    try 
    (
     // create TCP socket for the given hostName, remote port PortNumber 
     Socket echoSocket = new Socket(hostName, portNumber); 

    ) 
    { 
     String s = ""; 
     System.out.println("Sender til ip: " + hostName + " port: " + portNumber); 
     // Stream writer to the socket 
     out = new PrintWriter(echoSocket.getOutputStream(), true); 
     // Stream reader from the socket 
     in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream())); 
     out.println("connect"); 

     while((s = in.readLine()) != null && !s.isEmpty()) 
     { 
      switch (s) 
      { 
       case "red": 
        //set circle to red. 
        red.setFill(Paint.valueOf("#ff1f1f")); 
        System.out.println("red"); 
        break; 
       case "yellow": 
        //set circle to yellow 
        yellow.setFill(Paint.valueOf("#36bc0d")); 
        System.out.println("yellow"); 
        break; 
       case "green": 
        //set circle to green 
        green.setFill(Paint.valueOf("#bdff1f")); 
        System.out.println("green"); 
        break; 
       default: 
        break; 
      } 
     } 

     return echoSocket; 
    } 
    catch (UnknownHostException e) 
    { 
     System.err.println("Don't know about host " + hostName); 
     System.exit(1); 

    } catch (IOException e) 
    { 
     System.err.println("Couldn't get I/O for the connection to " + hostName); 
     System.exit(1); 
    } 
    return null; 
} 

问题是客户端输出从服务器接收到的参数,然后睡眠一段固定的时间,但它不会改变圆的颜色直到最后,并且所有的同时。

有没有人有解决这个问题?将不胜感激。

+0

我不明白这个问题,但它看起来像你想要在后台线程运行时更新某个圆圈上的颜色。你可以通过在''Platform.runLater()'] [https://docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#]中直接包装'setColor()'来做到这一点。 runLater-java.lang.Runnable-),或者你也可以使用['Task'](https://docs.oracle.com/javase/8/javafx/api/javafx/concurrent/Task.html)。 – ItachiUchiha

+0

嗨。是的,这是我想要实现的。我将如何使用Platform.runLater()来实现它? – ssandoy

+0

你应该通过[JavaFX - 控制和并发](http://stackoverflow.com/questions/24983721/javafx-control-and-concurrency) – ItachiUchiha

回答

1

在后台线程中运行你的clientStart方法和换行更改UI中Platform.runLater(...)来电:

while((s = in.readLine()) != null && !s.isEmpty()) { 
    final String line = s ; 
    Platform.runLater(() -> { 
     switch (line) 
     { 
      case "red": 
       //set circle to red. 
       red.setFill(Paint.valueOf("#ff1f1f")); 
       System.out.println("red"); 
       break; 
      case "yellow": 
       //set circle to yellow 
       yellow.setFill(Paint.valueOf("#36bc0d")); 
       System.out.println("yellow"); 
       break; 
      case "green": 
       //set circle to green 
       green.setFill(Paint.valueOf("#bdff1f")); 
       System.out.println("green"); 
       break; 
      default: 
       break; 
     } 
    }); 
} 

然后,你需要调用clientStart()的东西,如:

Task<Socket> clientStartTask = new Task<Socket>() { 
    @Override 
    public Socket call() { 
     return clientStart(); 
    } 
}); 

clientStartTask.setOnSucceeded(e -> { 
    Socket socket = clientStartTask.getValue(); 
    // do whatever you need with socket here... 
}); 

Thread thread = new Thread(clientStartTask); 
thread.setDaemon(true); 
thread.start(); 
+0

大大赞赏这个建议,但并不确定应该如何实现最后一块代码......我会在哪里放置该代码?当我按下连接按钮时,我启动clientStart()方法。那是我会把代码放在哪里?对不起,如果我不清楚.... – ssandoy

+0

你现在在哪里调用'clientStart()'?由于我发布的代码导致该方法被执行,这看起来像是显而易见的地方......所以,是的,你应该在你的处理程序中为连接按钮执行此操作。 –

+0

它的工作!哦,我的天啊,你救了我的命。非常感谢! – ssandoy

相关问题