【问题标题】:Separate threads for input and output in Java TCP ServerJava TCP Server 中输入和输出的独立线程
【发布时间】:2011-03-26 04:06:37
【问题描述】:

我的任务是用 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

这是一个合理的解决方案吗?

我遇到的另一个问题是,如果一个工作人员由于客户端断开连接而失败,我如何将其传达给另一个线程?如果一个线程出现故障,我想终止另一个线程。

谢谢

【问题讨论】:

    标签: java multithreading tcp client


    【解决方案1】:

    您不使用单独的输入和输出线程。你有一个套接字,你可以读写它。

    • 接受新连接
    • 启动新的连接处理程序线程并将该套接字交给它
    • 阻塞读取等待输入。
    • 处理输入,给出输出

    如果您需要让服务器在不从客户端获取输入的情况下输出某些内容,您可以通过超时阻止读取,或者使用Selector(看起来您正在使用 nio)

    我在这里的答案中给出了一个示例,可能会对您有所帮助:Checking for a client disconnect on a Java TCP server - output only

    这不是使用新的 NIO 类,而是显示如何使用带有超时的阻塞读取。

    【讨论】:

    • 感谢您的回答。这似乎是一个更好的解决方案。我已经按照你的建议改变了我的实现。我还有一个问题。我需要连接处理程序线程向服务器报告事件(消息接收/发送、断开连接)。是不是更好的做法;在处理程序构造函数中传递对服务器的引用,并让处理程序在引用上调用方法,还是使用观察者模式?
    • 也许一个聊天服务器到多个聊天客户端也可以很好.. 下面的示例代码将在服务器分派客户端数据的地方相互呼应(不过,您可以更改它以发送不同类型的数据) ...它使用旧式线程机制sochinda.wordpress.com/2010/04/01/…
    • @user677680 - 我会选择观察者模式,因为它在 java 中非常简单。让您的连接处理程序扩展 Observable 并让您的主线程实现 Observer 并向他们注册。
    • 感谢 cmets。非常感谢您的帮助。
    猜你喜欢
    • 2016-06-30
    • 2010-12-17
    • 2013-12-17
    • 1970-01-01
    • 1970-01-01
    • 2012-12-19
    • 1970-01-01
    • 1970-01-01
    • 2014-07-24
    相关资源
    最近更新 更多