【问题标题】:thread overwritten when new socket connects (Server/Client) multithread java新套接字连接(服务器/客户端)多线程java时覆盖的线程
【发布时间】:2015-07-23 12:51:53
【问题描述】:

我必须为 Uni 做一个线索游戏,所以我们有一个服务器类和正在连接的客户端。对于每个连接的客户端,我们希望使用正在连接的客户端的套接字启动一个自己的 ServerThread。这个线程只监听传入的消息并告诉服务器类将它们发送回客户端。 问题:每次新客户端连接时,他都会覆盖这个 ServerThread,所以总是只有一个 ServerThread,我们希望每个客户端都有一个。我们在客户端之间发送 JSON 消息,现在 ServerThread 中的接收消息仅从最后连接的套接字读取。我该如何解决这个问题?我在服务器中添加了我的接受方法,我想错误在那里,但可能在任何地方。谢谢你的帮助! 毛里求斯

服务器

public void accept() throws IOException{
        while(true){
            Socket socket = serverSocket.accept();
            Runnable r = new ServerThreadHandler(socket);
            Thread t = new Thread(r);
            t.start();
        }
    }

ServerThreadHandler:

public class ServerThreadHandler implements Runnable {
    static Socket socket=null;
    protected   User client;
    //private static  int i;
    private static BufferedReader in;
    private static OutputStreamWriter out;

    public  void createUser(String nick, String group, String[] ext) throws IOException{
        client = new User(nick, group, ext, null, false, 0, false, socket, socket.getPort());
    }

    /**
     * constructor-Method
     * @param socketS
     */
    ServerThreadHandler(Socket socketS){
        socket = socketS;
    }
    public void run(){
        Server.setThreadList(socket);
        in = createReader();
        out = createWriter();
        //and so on...
    }
}

【问题讨论】:

  • 胡乱猜测,ServerThreadHandler 中是否有可用的 static
  • 公共类 ServerThreadHandler 实现 Runnable { static Socket socket=null;受保护的静态用户客户端;
  • 摆脱静态,应该可以解决你的问题:)
  • protected static User client; ---> protected User client;
  • 感谢您的帮助!我尝试这样做,但我在 ServerthreadHandler 中有一个 createUser 方法,该方法在另一个类中调用,因此它必须是静态的,或者是否有另一种方法可以调用另一个类中的方法。那里还有一些读者和作家。为了得到它们,它们需要是静态的,不是吗?

标签: java multithreading sockets server overwrite


【解决方案1】:

您代码中提到的逻辑 sn-p 肯定会创建与 no 一样多的线程。正在连接的客户端。

但是,可能的原因可能是,由于 ServerThreadHandler 中的 Socket 变量是静态的,所有后续创建的线程都会覆盖相同的套接字变量,从而导致先前创建的使用套接字变量的线程出现问题。

您应该考虑在 ServerThreadHandler 中为 Socket 使用非静态变量,因为任何可运行的类都应该保持状态并且不应该使用静态套接字。

根据我从您的问题中了解到的情况, createUser 方法是 ServerThreadHandler 的一个实例方法。因此,您必须创建 ServerThreadHandler 的实例才能从另一个类调用 createUser。因此,即使它是实例变量,您也可以访问套接字变量。

【讨论】:

    【解决方案2】:

    不幸的是,代码有很多设计缺陷:

    我可以建议的最快解决方法是删除 User 类并移动 Handler 类中的所有内容(反之亦然?)

    也让你的所有变量non-static

        static Socket socket=null;
        protected   User client;
        //private static  int i;
        private static BufferedReader in;
        private static OutputStreamWriter out;
    

    他们应该是:

        Socket socket=null;
        protected   User client;
        //private int i;
        private BufferedReader in;
        private OutputStreamWriter out;
    

    【讨论】:

      【解决方案3】:

      Socket 成员变量应该是非静态的。读者和作者也是如此。

      除非您有充分的理由这样做并了解其后果,否则切勿将变量设为静态。

      【讨论】:

      • Inorite:( 为什么开发人员会直接插入静态代码?它需要更多的输入,并且会生成不可重入、线程不安全的代码。我只是不明白。
      猜你喜欢
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 2015-03-24
      • 2021-07-19
      • 2016-09-22
      • 1970-01-01
      相关资源
      最近更新 更多