我的任务是用Java编写tcp服务器和客户端。我在解决服务器的一般结构时遇到了一些麻烦。服务器必须接受多个连接,但没有请求响应协议。建立连接后,客户端可以将数据发送到服务器,服务器可以将数据发送到客户端。鉴于此,我认为每个连接都有一个单独的输入和输出线程是个好主意。我已经查看了很多示例,但大多数都非常简单,没有单独的输入和输出线程。我非常感谢任何帮助或建议。
到目前为止,我的tcp服务器有一个侦听客户端连接的侦听线程。建立连接后,我为该连接创建一个输入线程和一个输出线程。
在TCPServer中
while (true)
{
SocketChannel clientChannel = m_serverChannel.accept();
new Thread(new ReadWorker(clientChannel)).start();
new Thread(new WriteWorker(clientChannel)).start();
}
我应该如何传递要发送到输出线程的数据?我最初的想法是让输出线程监听待处理数据的队列,在数据可用时发送数据。
在TCPServer中
ConcurrentHashMap<SocketChannel, LinkedBlockingQueue<ByteBuffer>> pendingWrites
= new ConcurrentHashMap<SocketChannel, LinkedBlockingQueue<ByteBuffer>>();
void broadcast(ByteBuffer buffer) {
synchronized(pendingWrites) {
Iterator it = pendingWrites.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
((LinkedBlockingQueue<ByteBuffer>) pairs.getValue()).put(buffer);
}
}
在WriteWorker中
pendingWrites.get(socketChannel).take()
// send the data
这是一个合理的解决方案吗?
我遇到的另一个问题是,如果一个工作程序因客户端断开连接而失败,我该如何将其传达给另一个线程?如果一个线程出现故障,我想终止另一个线程。
由于
答案 0 :(得分:1)
您不使用单独的输入和输出线程。你有一个套接字,你可以读写它。
如果您需要让服务器输出一些内容而不从客户端获取输入,您可以使用超时阻止读取,或使用Selector
(看起来您正在使用nio)
我在这里的答案中举了一个例子,可以帮助你:Checking for a client disconnect on a Java TCP server - output only
这不是使用新的NIO类,而是展示了如何在超时时使用阻塞读取。