2011-11-03 34 views
0

得到了有关服务器 - 客户端的问题:爪哇 - 约插座:如何更改线程无需重新启动服务器

当服务器正在运行,如果我想在ServerThread一些变化,例如,字符串“欢迎您! “到“你好!”,是否可以执行,而无需重新启动服务器?现在,当我更改“欢迎!”时到别的地方,它仍然打印出“欢迎!”给客户。我必须关闭eclipse并重新启动服务器才能使用此新字符串。有什么办法可以解决这个问题吗?多谢!

服务器:

import java.net.*; 
import java.io.*; 

public class ATMServer { 

    private static int connectionPort = 8989; 
    public static void main(String[] args) throws IOException { 
    ServerSocket serverSocket = null; 
    boolean listening = true; 
    try { 
     serverSocket = new ServerSocket(connectionPort); 
    } catch (IOException e) { 
     System.err.println("Could not listen on port: " + connectionPort); 
     System.exit(1); 
    } 

    System.out.println("Bank started listening on port: " + connectionPort); 
    while (listening) 
     new ATMServerThread(serverSocket.accept()).start(); 
    serverSocket.close(); 
    } 
} 

ServerThread:

import java.io.*; 
import java.net.*; 

public class ATMServerThread extends Thread { 
    private Socket socket = null; 
    private BufferedReader in; 
    PrintWriter out; 
    public ATMServerThread(Socket socket) { 
     super("ATMServerThread"); 
     this.socket = socket; 
    } 

    public void run(){ 
    try { 
     out = new PrintWriter(socket.getOutputStream(), true); 

     out.println("Welcome!"); 

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

客户:

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

public class Client { 
    private static int connectionPort = 8989; 

    public static void main(String[] args) throws IOException { 

     Socket ATMSocket = null; 
     PrintWriter out = null; 
     BufferedReader in = null; 
     String adress = ""; 

     try { 
      adress = "127.0.0.1"; 
     } catch (ArrayIndexOutOfBoundsException e) { 
      System.err.println("Missing argument ip-adress"); 
      System.exit(1); 
     } 
     try { 
      ATMSocket = new Socket(adress, connectionPort); 
      out = new PrintWriter(ATMSocket.getOutputStream(), true); 
      in = new BufferedReader(new InputStreamReader 
            (ATMSocket.getInputStream())); 
     } catch (UnknownHostException e) { 
      System.err.println("Unknown host: " +adress); 
      System.exit(1); 
     } catch (IOException e) { 
      System.err.println("Couldn't open connection to " + adress); 
      System.exit(1); 
     } 

     System.out.println(in.readLine()); 


     out.close(); 
     in.close(); 
     ATMSocket.close(); 
    } 
} 
+0

这个问题是为什么IDE的有时是新开发一个危险的工具的例子。 @Ferry,如果你将你编写的代码在Eclipse之外进行一段时间的演示,你将学习到很多关于Java的知识。然后回到这里并重新制定你的问题。 – Perception

回答

3

这是可能的,但并不简单。

字符串“Welcome!”是类文件的一部分(它是一个静态的String常量)。当您更改它时,Eclipse将创建一个新的.class文件并将其写入磁盘。

与此同时,您有一个运行的Java程序使用相同的.class文件。有两个原因导致更改未被拾取:

  1. Java VM不会自动重新加载类文件。当一个类被加载一次时,它不会在更改磁盘上的.class文件时进行更新。您必须通知类加载器从内存中刷新加载的类并再次加载.class文件。

  2. 在正在运行的VM中有这个类的一个实例。该实例具有对String对象的引用。即使再次加载类,此实例(及其引用)也不会更改。你必须创建一个新的实例。

要解决第一个问题,您需要在调试模式下运行您的应用程序。然后,Eclipse将在.class文件发生更改时尝试告诉VM。请注意,有些虚拟机无法重新加载某些更改。例如,Sun的VM可以处理新的方法,方法参数,字段,导入。你只能改变方法体。 Eclipse会告诉你什么时候重装失败。

要解决第二个问题,请停止线程并启动一个新线程。我建议一个特殊的客户端“重新启动”消息,它会停止所有线程并创建一个新的池。

在任何情况下,都不需要停止Eclipse。

-1

我不知道我完全理解你的问题,但我想我知道你的”重新谈论。我相信发生了什么是你的应用程序没有关闭套接字,当你结束它。在Windows中,我不确定是否有办法在打开它的进程之外关闭该套接字,但在Linux中可以执行lsof然后杀死该pid。

lsof -i tcp:8989 
kill -9 some_PID 
+0

为了正确关闭套接字,请捕获您正在使用的中断或击键来结束应用程序,并调用线程中的函数来结束工作部分并关闭套接字。 – bdeetz

+0

这没有任何意义。如果应用程序结束,(a)操作系统释放所有资源,包括打开的套接字,并且(b)没有剩余的进程被终止。 – EJP

+0

@EJP它可能没有意义,但这并不改变我在某种程度上是正确的事实... http://stackoverflow.com/questions/2270343/cannot-bind-to-address-after-套接字程序崩溃 在他的情况下,我错了。他正在关闭插座,当我最初回答我忽略的问题时。但是,您可能会让应用程序崩溃,导致套接字处于TIME_WAIT状态。当发生这种情况时,您可以终止与该套接字关联的PID并重新获得再次打开套接字的能力。 – bdeetz

0

在你的线程上为你希望改变的变量创建一个setter方法。当你实例化线程时,保持你创建线程的句柄。然后简单地调用变量的setter方法。

2

我怀疑你以下面的方式误解 -

  • 您在Eclipse中点击“运行”,你的服务器启动
  • 你与客户
  • 更改服务器测试
  • 你再次点击'运行'
  • 您与客户端测试并且看到没有更改

这里发生的是第二次运行时,服务器无法启动,因为前一个服务器仍在运行&,因此新服务器无法获取侦听套接字。

您不需要重新启动Eclipse来终止正在运行的进程,只需进入控制台视图,使用工具栏中的“Open Console”下拉菜单(非常正确)下拉菜单找到正在运行的服务器进程并停止使用红色的停止按钮(非常左)。

+0

Thx。但是你的方法仍然需要重启服务器。想想如果服务器不是我的,我只有serverThread和客户端部分,我想更改字符串并使其工作。那可能吗? – Ferry