Java 帮助为每个连接的用户创建一个新的套接字

标签 java multithreading sockets stream connection

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

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

现在这段代码对于第一个连接的客户端来说可以完美工作。所有其他人根本无法连接。预先感谢所有提交答案的人。

最佳答案

你应该让一个线程始终执行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 中快速指出的那样.

关于Java 帮助为每个连接的用户创建一个新的套接字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16028434/

相关文章:

Android:在特定内核中运行进程或线程

c# - ThreadPool 线程执行 I/O 操作 - 线程可以在等待时重用吗?

java - 具有不可变参数的自引用枚举

java - Guava 事件总线 : Dispatching event to multiple subscribers

c++ - 同步工作线程

python asyncio socket在每个第一个连接上都低速

node.js - NodeJS 中的 Socket.io

java - 检索插入数字的双倍——客户端服务器编程

java - Java 和 C# 中使用 SHA-1 加密 ID 时,C# 有时会返回前面多一个 0 的值

java - 使用主体强制覆盖/扩展方法