2
votes

I'm trying to write a simple TCP client server connection. The server spawns a thread for each new client connection, and each thread talks to a client. I'm using DataInputStream and DataOutputStream classes, upon dis.readUTF() the server thread comes to a halt. I tried using BufferedReader and PrintStream/Printwriter, still the same issue. Please look for System.out.println("not here now"), that line preceding it blocks the execution.

/*
TCP client
*/

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient {

    public TCPClient() {
        // TODO Auto-generated constructor stub

    }

    public static void main (String args[]) throws UnknownHostException, IOException {

        Socket socket = new Socket("localhost", 9701);

        DataInputStream input = new DataInputStream(socket.getInputStream());

        DataOutputStream output = new DataOutputStream(socket.getOutputStream());

        //char[] buffer = new char[100];

        boolean stop = false;

        while (!stop) {

            System.out.println("here");
            output.writeBytes("hello server");

            String response = "-WTF-";
            System.out.println("here");

            response = input.readUTF();
            System.out.println("not here now");

            if (response == "kill") {
                stop = true;
            } else {
                System.out.println("5");
                output.writeBytes("talk to me");                
                System.out.println("received" + response);
            }
        }
        socket.close();
    }
}


/* TCP server */

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;


public class TCPServer extends Thread {

    final static int TCP_SERVER_PORT = 9701;
    private Socket socket;

    public TCPServer(Socket sock) {
        // TODO Auto-generated constructor stub
        socket = sock;

    }

    public void run()  {

        System.out.println(this.socket.getPort() + " working or sleeping for 5 seconds");

        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        DataInputStream clientinp;
        DataOutputStream clientout;

        try {
            clientinp = new DataInputStream(socket.getInputStream());
            clientout = new DataOutputStream(socket.getOutputStream());
            System.out.println("here");

            while (true) {
                System.out.println("here now");
                String sentence = clientinp.readUTF();   
                System.out.println("not here now");
                System.out.println(sentence);
                clientout.writeBytes(sentence);

            }

        }
        catch (IOException e) {

            System.out.println(e.getStackTrace());
        }
        finally {

            try {
                this.socket.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

        /*
         * other logic
         */     
    }

    public static void main(String args[]) throws IOException {

        ServerSocket serversocket;

        serversocket = new ServerSocket(TCP_SERVER_PORT);

        while (true) {
            Socket clientsocket = serversocket.accept();

            new TCPServer(clientsocket).start();

        }       
    }
}
2

2 Answers

9
votes

You are using writeBytes to write a string in the client and readUTF to read the same string in the server.

If you look at the javadocs for those two methods you will see that you are writing in one format and then reading in another. Specifically, readUTF expects the input to start with a 2 byte character count followed by a "modified UTF-8" encoding of the characters. But writeBytes just writes 1 byte per character. Typically, readUTF will attempt to read more bytes than writeBytes wrote ... and the socket stream will freeze.

You should use writeUTF instead of writeBytes ...

3
votes

Stephen C is right. I did some small modifications but the reason was 'use read* when using write* on the other side'.

Here's the running code:
Client:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;

public class TCPClient {

    public TCPClient() {
    }

    public static void main(String args[]) throws UnknownHostException, IOException {
        Socket socket = new Socket("localhost", 9701);
        DataInputStream input = new DataInputStream(socket.getInputStream());
        DataOutputStream output = new DataOutputStream(socket.getOutputStream());

        boolean stop = false;
        while (!stop) {
            System.out.println("client->server: hello...");
            output.writeUTF("hello");

            System.out.println("client: waiting...");
            String response = input.readUTF();
            System.out.printf("client: got response: %s\n", response);
        }
        socket.close();
    }
}

Server:

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

public class TCPServer extends Thread {

    final static int TCP_SERVER_PORT = 9701;
    private Socket socket;

    public TCPServer(Socket sock) {
        socket = sock;
    }

    public void run() {
        System.out.println(this.socket.getPort() + " working or sleeping for 5 seconds");

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        DataInputStream clientinp;
        DataOutputStream clientout;

        try {
            clientinp = new DataInputStream(socket.getInputStream());
            clientout = new DataOutputStream(socket.getOutputStream());

            while (true) {
                System.out.println("reading...");
                String sentence = clientinp.readUTF();
                System.out.printf("read: %s", sentence);
                clientout.writeUTF(String.format("answer: %s", sentence));
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String args[]) throws IOException {
        ServerSocket serversocket;
        serversocket = new ServerSocket(TCP_SERVER_PORT);
        while (true) {
            Socket clientsocket = serversocket.accept();
            new TCPServer(clientsocket).start();
        }
    }
}