我正在创建一个聊天服务器,但无法建立多个连接,我相信这是因为只有一个套接字。 我读过,一个线程一次可以处理多个套接字连接,但是每个客户端必须拥有自己的套接字。 像墙上的插座。 每个插头必须有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();
  }
}

现在,此代码对于第一个已连接的客户端非常有效。 所有其他人根本无法连接。 在此先感谢所有提交答案的人。

===============>>#1 票数: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 (大致是线程池),正如在此答案中迅速指出的那样。

===============>>#2 票数:0

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

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

这不能满足您的要求。 您的循环应该不做任何事情,只接受连接,然后为处理该套接字上所有I / O的每个线程启动一个新线程。 请参阅Java教程的“ 定制网络”部分。

===============>>#3 票数:0

您的套接字代码应类似于以下PSEUDO-CODE:

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

  ask by user2278118 translate from so

未解决问题?本站智能推荐:

1回复

套接字连接时CPU使用率过高

我有一个客户端类,它允许我连接到ntrip客户端服务(它基本上是一个http服务)。 此客户端允许我连接到安全和不安全的服务。 我正在使用javax.net库。 这是我的代码: 该代码对于安全连接和非安全连接均能正常工作。 但是,困扰我的是连接到不安全的服务时CPU使用率过高。
1回复

使用套接字的Java聊天程序无法正常工作

不知道标题是否具有误导性。 我无法弥补一个更好的。 关键是-我正在尝试为多个客户端建立一个非常简单的聊天程序,使其能够连接,并且我是主机(服务器)。 我已经到了一个客户端可以成功连接的地步,并且可以从客户端和服务器发送消息而没有任何问题。 但是,如果我连接了第二个客户端,我也可以
1回复

服务器中的一个循环,该循环读取所有客户端套接字

假设我有一个ServerReader类,它是一个一直运行的线程。 ServerReader具有一个循环,该循环以如下方式从所有客户端读取所有消息: 据我了解,当循环遇到readObject()方法时,线程将进入睡眠状态,直到客户端实际发送对象为止。 因此,想象一下这个场景:Array
4回复

使用Java从套接字的流中读取多个流?

有什么方法可以从打开的套接字流中随机读取字节吗? 假设我已经在网站上打开了数据流。 传统的Java类使我可以顺序访问数据。 就像一个链表。 我想随机读取数据,例如从数组的随机位置读取数据。 假设数据大小为2048 KB,我想用1个线程从0读取到1204 KB,同时要使用另一个线程从12
5回复

Java socketserver:如何处理许多传入连接?

我正在编写一个简单的多线程socketserver,我想知道如何最好地处理传入的连接: 为每个新连接创建一个新线程。 并发线程数将受到限制,并且通过指定积压来限制等待连接 将所有传入连接添加到队列中,并拥有一个处理队列的工作线程池 我倾向于选择2,因为我真的不想拒绝任
5回复

Java - 创建用于通过Internet发送对象的单独线程

我正在用Java编写Battleships游戏,用于我的学习中的事件驱动编程。 该游戏应该是一个网络游戏,我将在一个应用程序中创建客户端和服务器。 这是表示我的应用程序结构的图像: 类图http://dl.dropbox.com/u/41993645/mvc.jpeg 为了达到目的
5回复

在插座关闭后杀死一个线程

我想在客户端关闭套接字后杀死TCP连接侦听器线程(serverside)。线程在readLine()循环中等待..我该怎么办?
7回复

如何在没有关闭的情况下中断被某个套接字IO操作阻塞的线程

我真的想知道如何中断被某些I / O操作阻塞的线程? I / O是通过套接字,我不想close()套接字。 我尝试使用Thread.interrupt()来中断线程,但没有成功。 线程被IO操作阻止: 用于中断被阻塞线程的线程(不起作用):
1回复

无法使用serversocket在java中同时读取和发送请求

我已经编写了这个简单的Java服务器,可以使用服务器套接字接受端口上的连接。 我希望每当某些客户端尝试在同一局域网内的此端口上发送一些数据时,我想: 1.打印该数据,即:使用InputStreamReader从inputstream读取到缓冲区,然后打印到控制台。 2.使用OutP
1回复

Java代理未将任何内容发送回浏览器

我已经用Java创建了一个代理服务器(请参见下面的代码),问题是,我从Web服务器获取了响应,但是代理的客户端处理了客户端(浏览器)和Web之间的连接在使用代理的服务器端创建套接字后,使用-server。 服务器端创建一个客户端,并发送请求和套接字,然后在新线程中对其进行处理。 我有几个问题