Search code examples
javanetwork-programmingsocketchannel

Byte[] sent across SocketChannel but not received


I've been having some trouble with a project that requires a bit of networking, where data is sent over a SocketChannel but is never received. I was able to replicate the issue with a simple localhost chatroom program (sorry if it's a bit messy):

public class Main {

    private Sender sender; 

    private Receiver receiver;

    public static void main(String[] args) {
        Main foo = new Main();
        //The ports are switched in the other running version of this
        foo.receiver = new Receiver("192.168.1.108", 12348);
        foo.sender = new Sender("192.168.1.108", 12347);
        foo.takeUserInput();
    }
    private void takeUserInput() {
        while(true) {
            System.out.println("Enter something");
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            String input = null;
            try {
                input = br.readLine();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            sender.send(input);
        }
    }
}


public class Receiver implements Closeable {

    private InetSocketAddress bindAddress;

    private ServerSocketChannel server;

    private ListenThread listenThread;

    public Receiver(String address, int port) {
        bindAddress = new InetSocketAddress(address, port);
        bind();
        listen();
    }

    public void bind() {
        try {
            server = ServerSocketChannel.open();
            server.configureBlocking(true);
            server.bind(bindAddress);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("Bound to port " + bindAddress.getPort());
    }
    public void listen() {
        listenThread = new ListenThread();
        listenThread.start();
    }
    private class ListenThread extends Thread {

        private SocketChannel client;

        public void run() {
            try {
                client = server.accept();
                System.out.println("Received connection from " + client.getLocalAddress());
            } catch (IOException e) {
                e.printStackTrace();
            }
            while((server.isOpen()) && (client.isOpen())) {
                byte[] bytes = new byte[4096];
                ByteBuffer buffer = ByteBuffer.wrap(bytes);
                try {
                    System.out.println("Reading");
                    client.read(buffer);
                    System.out.println(new String(buffer.array()));
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

            }
        }
    }

    @Override
    public void close() throws IOException {
        server.close();
        listenThread.client.close();
    }
}

public class Sender implements Closeable {

    private InetSocketAddress connectAddress;

    private SocketChannel clientChannel;

    public Sender(String address, int port) {
        connectAddress = new InetSocketAddress(address, port);
        connect();
    }

    public void connect() {
        while((clientChannel == null) || (!(clientChannel.isConnected()))) {
            try {
                clientChannel = SocketChannel.open(connectAddress);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        try {
            System.out.println("Connected to " + clientChannel.getLocalAddress());
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void send(String message) {
        byte[] bytes = message.getBytes();
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        try {
            clientChannel.write(buffer);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Sent message");
    }

    @Override
    public void close() throws IOException {
        clientChannel.close();
    }
}

Here's the logs from one version:

Bound to port 12348
Reading
Connected to /192.168.1.108:64699
Enter something
thing
Sent message
Enter something

And the other:

Bound to port 12347
Reading
Connected to /192.168.1.108:64698
Enter something

So, I know that both programs successfully establish connections to the other, and start reading, but when I send something over a SocketChannel from one end, the other just remains stuck on the read()call in ListenThread.

How can I make the client successfully read what is sent?


Solution

  • I can see two issues.

    1. As mentioned by @Ethan F, the ports are different. You should use the same port number.

    2. Your listen() method in the Receiver class never get called. You need to call this method to accept connection.

      foo.receiver = new Receiver("192.168.1.108", 12348);
      foo.receiver.listen();