代码之家  ›  专栏  ›  技术社区  ›  Kevin Boyd

服务于客户端的Java套接字服务器

  •  1
  • Kevin Boyd  · 技术社区  · 14 年前

    有没有一种方法来实现串行为客户机服务的套接字服务器?
    通常的做法是将连接的客户机分派到一个新的线程,该线程为请求和响应提供服务,但在服务器端,每个客户机的线程数为一个。

    我不想这么做,因为后来我想把这个应用程序移植到JavaME上,这可能限制了在一个时间点运行的并发线程的数量。

    我在想怎么解决这个问题?

    5 回复  |  直到 13 年前
        1
  •  4
  •   Draemon    14 年前

    当然,只是不要触发后台线程来处理客户机。

    编辑

    似乎您真正想要的是让大量客户机能够连接,但不创建线程负载。由于似乎不支持NIO,如何使用两个线程:

    • 一个线程循环接受连接,传递连接的 Socket 到第二个线程,该线程只将其添加到已连接的套接字列表中(需要同步此线程)
    • 第二个线程,循环遍历其内部的活动连接列表,并依次对每个线程执行“一些工作”。

    打电话 socket.setSoTimeout() 使用一个相当小的值应该可以防止第二个线程在一个连接上等待太长时间。

        2
  •  1
  •   Jherico    14 年前

    通常,服务器处理如下所示:

        ServerSocket s;
        Socket newSocket;
        while (newSocket = s.accept()) {
            new SocketHandlingThread(newSocket).start();
        }
    

    其中sockethandlingthread()是您创建的一个类,用于执行socket会话的服务器端应该执行的任何操作。

    有两种基本方法可以满足您的要求(即处理插座) 同步地 )。第一种方法是简单地在处理程序线程上联接,然后再移回accept(),如下所示

        while (newSocket = s.accept()) {
            SocketHandlingThread thread = new SocketHandlingThread(newSocket);
            thread.start();
            thread.join();
        }
    

    正如下面的注释中指出的,您可以通过这样调用线程的run方法来避免连接。

     thread.run(); 
    

    代替开始和加入呼叫。

    另一种方法是获取sockethandlingthread的run方法中的任何代码,并将其直接移动到循环中。

        3
  •  1
  •   Pool    14 年前

    有一个很好的服务器端套接字处理示例,包括可以找到的池 here .

    但是,考虑到您可能实际上不需要池——我可以从一个服务器为800个同时的客户机(每个客户机都有自己的专用套接字线程)提供服务。

        4
  •  1
  •   Todd Stout    14 年前

    您可以使用非阻塞套接字。如果您这样做,那么您就不需要为每个客户机提供线程。Java已经支持了这一段时间。 NIO . 我不确定这是否是JavaME支持的。JavaME是近年来发展起来的,它包括JSE的许多特性。在JavaME环境中需要服务器端功能,这可能有点不寻常,需要为许多客户端连接服务。

    在您的情况下,流量是否仍然没有通过服务器路由?如果是这样,J2ME环境就没有理由不能通过到服务器的单个套接字连接接收来自许多其他客户机或对等机(如果您想这样调用它们)的消息。

        5
  •  0
  •   malaverdiere    14 年前

    您可以在接受套接字上设置一个sou超时。这将强制接受调用不阻塞。这样,您可以等待一小段时间,然后服务于一个以前接受的连接,然后返回到接受新的连接,等等。代码看起来像这样:

    do(
      try{
        socket.setSoTimeout(200);
        Socket connected = socket.accept()
      } catch (SocketTimeoutException e){//just ignore}
      //handle your other threads/connections here
    } while (!shutDown)