2010-01-16 88 views
1

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

我不想这样做,因为我后来想将此应用程序移植到Java ME,这可能会限制在某个时间点运行的并发线程数。

我想知道如何解决这个问题?

回答

4

当然,只是不发射后台线程来处理客户端。

编辑

好像你真正想要的是能够连接大量的客户端,但不能创建线程的负载。由于NIO似乎没有被有关使用两个线程如何支持:

  • 一个线程循环接受连接,通过连接的Socket到只是增加了它连接的套接字的列表,第二个线程(这必须是同步)
  • 第二个线程通过其活动连接的内部列表进行循环,并依次进行“一些工作”。

调用socket.setSoTimeout()的值相当小应该可以防止第二个线程在一个连接上等待太久。

+0

如何处理请求和响应,以及在其他客户端想要连接时如何实现机制。服务器是否能够将数据推送到客户端,或者该设备在此机制下是否无法使用。 – 2010-01-16 00:40:29

+0

你说你想要连续处理连接 - 其他客户端将无法连接。这不是你想要的吗? – Draemon 2010-01-16 00:44:58

+0

我的印象是,一旦你听到客户端将排队到本地tcp堆栈的限制,并且使用accept将它们从堆栈中拉出来。其他客户端将能够连接,但直到服务器处理每个人之前都不会收到数据。 – Jherico 2010-01-16 00:48:26

1

通常服务器处理看起来是这样的:

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

其中SocketHandlingThread()是您创建做一个类无论插座谈话的服务器端应该是。

有两种基本的方法可以做你正在问的问题(即同步处理插座)。首先是重新搬回到接受(),这样

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

正如下面的评论中指出之前的处理器线程上简单地加入,可以在避免只调用像线程的run方法的加入所以

thread.run(); 

代替开始和加入呼叫。

另一种方法是采取SocketHandlingThread的run方法中的任何代码并将其直接移入循环。

+0

我认为你的意思是thread.start()不是thread.run(),你可以通过调用thread.run()来实现你的第二个方法 - 不需要thread.join() – Draemon 2010-01-16 00:43:28

+0

指出固定错误。 – Jherico 2010-01-16 00:46:37

+0

加入会导致调用进程在返回之前等待您加入的线程完成。它基本上是一个'等到这件事完成'的功能。 – Jherico 2010-01-16 00:47:21

1

您可以使用非阻塞套接字。如果你这样做,那么你不需要每个客户端的线程。 Java已经通过NIO支持了一段时间。我不确定这是否受Java ME支持。 Java ME现在正在成长,因此它包含了JSE的许多功能。在需要服务许多客户端连接的Java ME环境中具有服务器端功能可能有点不寻常。

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

+0

对于p2p聊天应用程序,我需要实现这种机制。对不起,说J2ME不支持NIO。 – 2010-01-16 00:47:29

+0

在这种情况下,没有服务器是一台电话充当服务器。 – 2010-01-16 02:43:00

+0

你的客户如何发现手机的IP地址和端口? – 2010-01-16 02:47:12

0

您可以在接受套接字上设置SO_TIMEOUT。这将强制接受呼叫是非阻塞的。这样你就可以等待一段时间,然后服务一个以前接受的连接,然后回到接受新的连接,等等。该代码会隐约看起来像这样:

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

你能详细说一下吗? – 2010-01-16 00:53:03

+0

添加代码到原来的帖子来说明 – malaverdiere 2010-01-29 13:54:10

+0

它会强制它阻塞超时。这与非阻塞不同。 – EJP 2015-11-25 12:08:45

1

还有就是服务器端的socket处理包括资源池,可以发现here一个很好的例子。

然而,考虑一下,你可能并不需要池 - 我从一台服务器为每个服务800个并发客户端都有自己的专用套接字线程没有问题。

+0

将检查链接,800线程看起来相当不错,这里的问题是我想将代码移植到Java ME,并且它可能有问题,甚至有5个并发线程。我试图在这里用所有的手机玩这个游戏。 – 2010-01-16 01:49:36

+1

啊,对不起,我以为你的意思是你有很多ME客户端连接到你控制的服务器。我在ME上支持的最小支持线程的快速谷歌发现以下内容:http://discussion.forum.nokia.com/forum/showthread.php?t=79232 您是否想过通过中央服务器传递所有通信?由于沙盒限制,我会认为这样做必须这样做,但是我已经碰到了Java ME很长一段时间了! – Pool 2010-01-16 01:58:53

+0

我已经给了它一个想法,但现在我不能通过该实现,非常感谢这个链接,这确实是非常有用的,它给了我一些线索什么新的文档挖掘和检查新的线程规格。那么J2ME平台有一些限制,但它已经有了很大的改进。希望我能给你+2。干杯! – 2010-01-16 02:16:52