【问题标题】:Java help creating a new socket per connected userJava 帮助为每个连接的用户创建一个新的套接字
【发布时间】:2013-04-08 08:23:41
【问题描述】:

我正在创建一个聊天服务器,但我无法建立多个连接,我相信这是因为只有一个套接字。我读过一个线程一次能够处理多个套接字连接,但每个客户端都必须有自己的套接字。像墙上的插座。每个插头必须有 1 个插座。如何为每个客户端创建一个套接字以用于与服务器通信?我将提供一些代码来帮助你们建立你的帮助。这是接受单个套接字(连接)的地方。

 private void waitForConnection() throws IOException
 {
     connection = server.accept();
     showMessage("\nNow connected to " + connection.getInetAddress().toString());
     clientCount += 1;
 }

这里是在服务器启动时调用代码的地方:

public void startRunning()
{
  try
  {
     server = new ServerSocket(1337, 10);
     while(true)
     {
        try
        {
            showMessage("Waiting For a Player To Connect...");
            waitForConnection();
            setupStreams();
            whileChatting();

        }
        catch(EOFException eofException)
        {
           showMessage("\n Server ended the connection! ");
        }
        finally
        {
           closeConnections();
        }
     }
  }
  catch(IOException ioException)
  {
     ioException.printStackTrace();
  }
}

现在这段代码完美地适用于第一个连接的客户端。所有其他人根本无法连接。提前感谢所有提交答案的人。

【问题讨论】:

    标签: java multithreading sockets stream connection


    【解决方案1】:

    您应该让一个线程始终执行socket.accept()。那就是:

    • 每当您收到客户(通过socket.accept()),您应该
      • 创建一个新的Thread,从现在开始照顾那个客户。 (我称之为Thread扩展类ClientNanny);
      • 然后重新运行socket.accept()

    这就是你的waitForConnection() 方法应该是这样的:

    private List<ClientNanny> clients = new ArrayList<ClientNanny>();
    
    private void waitForConnection() throws IOException
    {
         while (true) { /* or some other condition you wish */
             connection = server.accept(); /* will wait here */
             /* this code is executed when a client connects... */
    
             showMessage("\nNow connected to " 
                                          + connection.getInetAddress().toString());
    
             ClientNanny nanny = new ClientNanny(connection); /* call a nanny to take
                                                                 care of it */
             clients.add(nanny); /* make sure you keep a ref to it, just in case */
             nanny.start(); /* tell nanny to get to work as an independent thread */
             clientCount += 1; /* you dont need this: use clients.size() now */
         }
    }
    

    如果您没有注意到,ClientNanny 应该类似于:

    class ClientNanny extends Thread {
        ClientNanny(Socket baby) {
            this.myBaby = baby;
        }
        @Override
        public void run() {
            bed.put(myBaby); /* and probably other commands :) */
        }
    }
    

    现在,您应该注意到下面突出显示的代码...

    try
    {
        showMessage("Waiting For a Player To Connect...");
        waitForConnection();
        setupStreams();  /* <--------- THIS LINE! HI! I'M A HIGHLIGHT! */
        whileChatting(); /* <--------- THIS LINE! HI! I'M A HIGHLIGHT TOO! */
    }
    

    按照我的建议更改waitForConnection() 时不会执行(因为waitForConnection() 将继续在while(true) 循环内滚动)。也许您可以将socket.accept() 放在它自己的线程上...无论如何,我相信您可以从现在开始接受它,是吗?

    PS.:作为最终指针,上面的解决方案使用new Thread()(或new ClientNanny())作为解释问题的最简单方法。不过,非常理想的解决方案可能涉及使用ExecutorService(大致是一个线程池),正如this answer 中快速指出的那样。

    【讨论】:

      【解决方案2】:

      你的代码的整个结构是错误的:

      waitForConnection();
      setupStreams();
      whileChatting();
      

      这不能满足您的要求。你的循环除了接受连接之外什么都不做,然后为每个处理该套接字上的所有 I/O 的线程启动一个新线程。请参阅 Java 教程的 Custom Networking 部分。

      【讨论】:

        【解决方案3】:

        您的套接字代码应如下所示:

        create server socket
        while true (or quit received) {
            accept connection
            spawn thread to handle communication
        }
        

        也就是说,您需要为每个连接生成一个线程。然后每个线程都可以执行whileChatting(),而不是阻塞主线程。

        例子:

        while (true) {
            try {
                // listen for client connections
                Socket s = svr.accept();
        
                // start a separate thread to handle this client's communications
                new ChatClientHandler(s).start();
            }
            catch (IOException e) {
                // print out the error, but continue!
                System.err.println(e);
            }
        }
        

        【讨论】:

          猜你喜欢
          • 2020-09-02
          • 2017-04-26
          • 2018-01-19
          • 2011-05-04
          • 2012-08-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多