Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java-关于套接字:如何在不重新启动服务器的情况下更改线程_Java_Sockets_Client Server - Fatal编程技术网

Java-关于套接字:如何在不重新启动服务器的情况下更改线程

Java-关于套接字:如何在不重新启动服务器的情况下更改线程,java,sockets,client-server,Java,Sockets,Client Server,服务器客户端出现问题: 当服务器运行时,如果我想在ServerThread中做一些更改,例如,字符串“Welcome!”到“Hello!”,是否可以在不重新启动服务器的情况下执行这些更改?现在,当我将“欢迎!”改为其他内容时,它仍然会向客户打印“欢迎”。我必须关闭eclipse并重新启动服务器才能使这个新字符串正常工作。有没有办法解决这个问题?太多了 服务器: import java.net.*; import java.io.*; public class ATMServer {

服务器客户端出现问题:

当服务器运行时,如果我想在ServerThread中做一些更改,例如,字符串“Welcome!”到“Hello!”,是否可以在不重新启动服务器的情况下执行这些更改?现在,当我将“欢迎!”改为其他内容时,它仍然会向客户打印“欢迎”。我必须关闭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();
    }
}
服务器线程:

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

我不确定我是否完全理解你的问题,但我想我知道你在说什么。我相信现在的情况是,当您结束应用程序时,它并没有关闭套接字。在Windows中,我不确定是否有办法在打开套接字的进程之外关闭该套接字,但在Linux中,可以这样做,然后lsof杀死该pid

lsof -i tcp:8989
kill -9 some_PID

我不确定我是否完全理解你的问题,但我想我知道你在说什么。我相信现在的情况是,当您结束应用程序时,它并没有关闭套接字。在Windows中,我不确定是否有办法在打开套接字的进程之外关闭该套接字,但在Linux中,可以这样做,然后lsof杀死该pid

lsof -i tcp:8989
kill -9 some_PID

在线程上为要更改的变量创建setter方法。在实例化线程时,保留所创建线程的句柄。然后简单地调用变量的setter方法。

在线程上为要更改的变量创建setter方法。在实例化线程时,保留所创建线程的句柄。然后简单地调用变量的setter方法。

我怀疑您误解了以下方式-

  • 在Eclipse中点击“Run”,服务器启动
  • 您可以使用客户端进行测试
  • 您可以更改服务器
  • 你又跑了
  • 您使用客户端进行测试,没有看到任何更改
这里发生的情况是,第二次点击run时,您的服务器无法启动,因为前一个服务器仍在运行&因此新服务器无法获取listen套接字


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

我怀疑您误解了以下方式-

  • 在Eclipse中点击“Run”,服务器启动
  • 您可以使用客户端进行测试
  • 您可以更改服务器
  • 你又跑了
  • 您使用客户端进行测试,没有看到任何更改
这里发生的情况是,第二次点击run时,您的服务器无法启动,因为前一个服务器仍在运行&因此新服务器无法获取listen套接字


您不需要重新启动Eclipse来终止正在运行的进程,只需转到控制台视图,使用工具栏中的“打开控制台”下拉列表(非常右)来查找正在运行的服务器进程,并使用红色停止按钮(非常左)停止它。

这是可能的,但并不简单

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

同时,您有一个正在运行的Java程序,它使用相同的.class文件。有两个原因导致更改未被接受:

  • Java虚拟机不会自行重新加载类文件。类加载一次后,当您更改磁盘上的.class文件时,它不会更新。您必须告诉类加载器从内存中刷新加载的类,然后再次加载.class文件

  • 正在运行的VM中存在此类的实例。实例具有对字符串对象的引用。即使再次加载该类,该实例(及其引用)也不会更改。您必须创建一个新实例

  • 要解决第一个问题,您需要在调试模式下运行应用程序。Eclipse随后将尝试告诉VM.class文件何时发生了更改。请注意,某些VM无法重新加载某些更改。例如,Sun的VM可以处理新方法、方法参数、字段和导入。只能更改方法体。Eclipse将告诉您重新加载失败的时间

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


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

    这是可能的,但并不简单

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

    同时,您有一个正在运行的Java程序,它使用相同的.class文件。有两个原因导致更改未被接受:

  • Java虚拟机不会自行重新加载类文件。类加载一次后,当您更改磁盘上的.class文件时,它不会更新。您必须告诉类加载器从内存中刷新加载的类,然后再次加载.class文件

  • 正在运行的VM中存在此类的实例。实例具有对字符串对象的引用。即使再次加载该类,该实例(及其引用)也不会更改。您必须创建一个新实例

  • 要解决第一个问题,您需要在调试模式下运行应用程序。Eclipse随后将尝试告诉VM.class文件何时发生了更改。请注意,某些VM无法重新加载某些更改。例如,Sun的VM可以处理新方法、方法参数、字段和导入。只能更改方法体。Eclipse将告诉您重新加载失败的时间

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

    在任何情况下,都没有必要去做