1

I'm trying to code a server-client communicating application which uses two separate threads, one for input and one for output. I'm having a weird "deadlock" issue, though: when one thread reads input, but the client hasn't sent anything, the thread stops (since it's waiting for input). However, for some reason, while the input thread is blocked, the output thread can't write anything.

This is illustrated in this code sample:

import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;

public class TestServer {
    public static void main(String... args) throws IOException {

        /* Creates a server socket that lurks about our port waiting for connections */
        ServerSocketChannel serverChannel = ServerSocketChannel.open();
        serverChannel.configureBlocking(false);
        serverChannel.socket().bind(new InetSocketAddress(4114));


        while(true){
            SocketChannel connectionChannel = serverChannel.accept();
            if(connectionChannel != null){
                final Socket connection = connectionChannel.socket();


                new Thread(){
                    public void run(){
                        try {
                            System.out.println("READING");
                            System.out.flush();
                            // If the next line is commented out, nothing blocks
                            connection.getInputStream().read();
                            System.out.println("DONE READING");
                            System.out.flush();
                        } catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }.start();

                new Thread(){
                    public void run(){
                        try {
                            System.out.println("WRITING");
                            System.out.flush();
                            new DataOutputStream(connection.getOutputStream()).writeBytes("AUGH!!!");
                            //connection.getOutputStream().write(5);
                            System.out.println("DONE WRITING");
                            System.out.flush();
                        } catch (Exception e){
                            e.printStackTrace();
                        }
                    }
                }.start();

                break;
            }
        }
    }
}

And the client code:

import java.net.*;
import java.io.*;

public class TestClient {

    public static void main(String... args) throws IOException {
        Socket connection = new Socket("127.0.0.1", 4114); 
        while(true){
            System.out.println(connection.getInputStream().read());
        }
    }

}

The code sample above blocks, but if the line in the server is commented out it doesn't. Why is that? Is a socket limited to only waiting for input/output at the same time? What's going on?

Nifty
  • 11
  • 1
  • 2
  • I'm surprised by this behavior, but it seems strange to me to handle input and output for a single client in two separate threads. Most thread-based systems use a single thread per client. (And, I thought one of `nio`'s big calling features was that it let you write servers without using threads -- is it thread-safe?) – sarnold Mar 17 '11 at 22:29
  • I also noticed that if I switch the line with the DataOutputStream for the line that just uses a direct OutputStream things start to work. Does DataOutputStream send some sort of headers that mess these things up? What's going on? – Nifty Mar 17 '11 at 22:42
  • I believe DataOutputStream doesn't send any header data, ObjectOutputStream certainly does, but still, that should effect your problem. – MeBigFatGuy Mar 17 '11 at 22:45

1 Answers1

2

I'm not sure why you are seeing this, but it has something to do with using channels.

If you replace this code with

ServerSocket ss = new ServerSocket(4114);
Socket connection = ss.accept();

it will work as you want.

MeBigFatGuy
  • 28,272
  • 7
  • 61
  • 66