简体   繁体   中英

Separate threads for input and output in Java TCP Server

I've been tasked with writing a tcp server and client in Java. 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. Once a connection is made, I create an input thread and an output thread for that connection.

In 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

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

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)

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

This is not using the new NIO classes, but shows how you would use a blocking read with a timeout.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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