我正在尝试为单线程物理产品编写模拟器。它接受一个长期连接,并且任何其他连接都会收到一条错误消息(在同一个线程中)。
我知道我可以使用带有两个线程的java.net:
但是我怎么能用一个线程做到这一点,所以它的行为更像物理产品(即重复尝试连接会使线程不能处理第一个连接)?
尝试不使用第三方库,但如果这是唯一的选择,可以这样做。
谢谢!
答案 0 :(得分:2)
不幸的是,常见的java.net.ServerSocket
以及java.nio.channels.ServerSocketChannel
只有一种阻止方法来接受传入的连接。但是,java.nio
包具有许多其他类和方法,可以通过多路复用打开的通道来处理单个线程中的I / O操作。
此方法仍然会为接受ServerSocketChannel
强制执行专用线程,但您可以在单个线程中处理每个接受的连接。
相比之下,ServerSocket
方法需要为每个新连接添加一个新线程
Imgaine你使用ServerSocket
连接100个客户端,那么你最终会得到101个线程。使用ServerSocketChannel
, 最终只能使用2个帖子。
仍然编程通常是在复杂性/灵活性和性能之间进行权衡。所以记住这一点。
我能想到的一个可能的解决方案可能是这样的:
public static void main( String[] args ) throws IOException
{
int portNr = 8080;
ExecutorService es = Executors.newSingleThreadExecutor();
ChannelHandler ch = new ChannelHandler();
es.execute( ch );
// Starting server:
ServerSocketChannel serv = ServerSocketChannel.open();
// Bind socket to Port
serv.socket().bind(new InetSocketAddress(portNr));
while( serverAlive )
{
ch.addChannel(serv.accept());
}
serv.close();
}
您实际处理新添加的SocketChannel
的方式取决于您的应用程序。 ChannelHandler#addChannel
方法也是如此。
答案 1 :(得分:0)
您似乎应该接受单一连接,然后关闭ServerSocket
。任何未来的连接尝试都将获得连接拒绝。当长期连接结束时,创建一个新的ServerSocket
,再接受一个连接,......冲洗并重复。
编辑如果您必须按照下面的评论发送错误消息,则必须接受连接以将其发送,并且如果您必须执行I / O并接受所有操作线程你必须使用java.nio.channels.ServerSocketChannel/SocketChannel
,非阻止模式和Selector
。
答案 2 :(得分:-1)
将ServerSocket与一个线程一起使用根本不是一个好主意。为什么?
你知道socket.accept()等到下一个客户端连接,所以线程被阻塞,如果你只有一个线程,你的整个Programm被阻塞,直到客户端连接。
你可以解释为什么你尝试单线程吗?
如果您有兴趣,我已经编写了一个(免费的,开源的,Creative Commons)API,它也使用AES 128加密数据