简体   繁体   English

Java TCP Server中用于输入和输出的单独线程

[英]Separate threads for input and output in Java TCP Server

I've been tasked with writing a tcp server and client in Java. 我的任务是用Java编写TCP服务器和客户端。 I'm having some trouble working out the general structure of my server. 我在确定服务器的一般结构时遇到了一些麻烦。 The server must accept multiple connections but there is no request response protocol. 服务器必须接受多个连接,但是没有请求响应协议。 Once a connection is made, the client can send data to the server, and the server can send data to the client. 建立连接后,客户端可以将数据发送到服务器,而服务器可以将数据发送到客户端。 Given this, I decided it would be a good idea for each connection to have seperate input and output threads. 鉴于此,我认为将每个连接都具有独立的输入和输出线程是一个好主意。 I've looked through lots of examples but most are quite simple and don't have separate threads for input and output. 我浏览了许多示例,但大多数示例都非常简单,没有用于输入和输出的单独线程。 I'd greatly appreciate any help or advice. 我将不胜感激任何帮助或建议。

So far, my the tcp server has a listening thread which listens for client connections. 到目前为止,我的tcp服务器具有一个侦听线程,用于侦听客户端连接。 Once a connection is made, I create an input thread and an output thread for that connection. 建立连接后,我将为该连接创建一个输入线程和一个输出线程。

In TCPServer 在TCPServer中

while (true)
{
    SocketChannel clientChannel = m_serverChannel.accept();         
    new Thread(new ReadWorker(clientChannel)).start();
    new Thread(new WriteWorker(clientChannel)).start();
}

How should I pass the data to be sent to the output threads? 我应该如何传递要发送到输出线程的数据? My initial thoughts were to have the output threads listen on a queue of pending data, sending the data as it becomes available. 我最初的想法是让输出线程在未决数据队列上侦听,并在数据可用时发送数据。

In TCPServer 在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);
    }
}

In WriteWorker 在WriteWorker中

pendingWrites.get(socketChannel).take()
// send the data

Is this a reasonable solution? 这是一个合理的解决方案吗?

The other problem I'm having is if one worker fails due to client disconnection, how can I communicate this to the other thread? 我遇到的另一个问题是,如果一个工作程序由于客户端断开而失败,如何将其传达给另一个线程? If there is a failure in one thread, I'd like to terminate the other. 如果一个线程失败,我想终止另一个线程。

Thanks 谢谢

You do not use separate input and output threads. 您不使用单独的输入和输出线程。 You have a socket, you can read and write to it. 您有一个套接字,可以对其进行读写。

  • accept new connection 接受新的连接
  • start new connection handler thread and hand that socket to it 启动新的连接处理程序线程并将该套接字传递给它
  • blocking read waiting for input. 阻止读取等待输入。
  • process input, give output 处理输入,输出

If you need to have the server output something without getting input from the client, you would blocking read with a timeout, or use a Selector (It looks like you're using nio) 如果您需要服务器输出某些内容而没有从客户端获取输入,则可以使用超时来阻止读取,或者使用Selector (好像您正在使用nio)

I gave an example in an answer here on SO that may help you: Checking for a client disconnect on a Java TCP server - output only 我在一个关于SO的答案中给出了一个示例,该示例可以帮助您: 检查Java TCP服务器上的客户端断开连接-仅输出

This is not using the new NIO classes, but shows how you would use a blocking read with a timeout. 这不是使用新的NIO类,而是显示了如何使用带超时的阻塞读取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM