2

I'm trying to learn sockets using Java and I sucessfully sent data to a ServerSocket running in my own machine. When I try to read from this socket using readline (so I can just echo my own sent message) my program hangs and won't return.

Here's the code:

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

    TCPClient cli = new TCPClient("127.0.0.1", "15000");
    try {
        cli.ostream.writeUTF("Teste");
        String echo = cli.istream.readLine(); //it hangs in this line
        System.out.println(echo);
    }

TCPClient is a class I defined so I can test my program on a simpler interface before using swing on my homwework. here's the code:

public class TCPClient {

public DataOutputStream ostream = null;
public BufferedReader istream = null;

public TCPClient(String host, String port) throws UnknownHostException {
    InetAddress ip = InetAddress.getByName(host);

    try {
        Socket socket = new Socket(host, Integer.parseInt(port));

        ostream = new DataOutputStream(socket.getOutputStream());
        istream = new BufferedReader(new InputStreamReader(socket.getInputStream()));


    } catch (IOException ex) {
        Logger.getLogger(TCPClient.class.getName()).log(Level.SEVERE, null, ex);
    }

}

My server is pretty simple. After the connection is estabilished, it enters in this loop and stays here until I close the client (because of the infinite loop). Afterwards, some exception handling returns it to the point before the connection started.

            while(true){
                String msg = istream.readLine();
                System.out.println("Arrived on server: " + msg); //just works on debug
                ostream.writeUTF("ACK: " + msg);
                ostream.flush();
            }

I don't see what am I missing.

PS: the wierd stuff is that if I debug the server, I can see the message arriving there (I can print it, for example), but this isn't possible if I just run this code. Does this have some concurrency relation I'm overlooking?

thx

Thiago Moraes
  • 617
  • 1
  • 10
  • 22
  • 1
    What does the server do? If it doesn't answer anything to your message, or doesn't flush its write, then of course the client will wait indefinitely until a line is sent from the server – JB Nizet Oct 21 '11 at 22:11
  • I'll edit the post with the server's infinite loop while echoing messages – Thiago Moraes Oct 21 '11 at 22:13

3 Answers3

11

The problem is that readLine tries reading a line. It will not return the line until it's sure that the end of line has been reached. This means that it expects either a newline character, or the end of the communication. Since the server doesn't send any newline char and doesn't close the stream, the client waits indefinitely.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 1
    That's it! Putting a '\n' in ostream.writeUTF("ACK: " + msg); worked. The only doubt now is that 2 non-printable characters appeared on my client. What can they be? – Thiago Moraes Oct 21 '11 at 22:22
  • 1
    You write in UTF at one side, and read using the platform's default encoding on the other side. Always use a Writer to write characters. Always wrap the output stream with an OutputStreamWriter which specifies a specific, explicit encoding. Do the same to read : always use a Reader, and wrap the input stream with an InputStreamReader which specifies the same specific encoding. – JB Nizet Oct 21 '11 at 22:25
  • @Thiago Moraes They are the length word prefix put there by writeUTF() as documented in the Javadoc. See also my answer. – user207421 Oct 21 '11 at 22:26
  • Now it works properly. I used OutputStreamWriter and BufferedReader. But I still have to send "\n" from the client and from the server so that everything can work. On the brightside, I didn't have problems with encoding anymore. – Thiago Moraes Oct 21 '11 at 22:42
  • @ThiagoMoraes see my answer. It's all in there. Curious that you marked this one as correct really. – user207421 Oct 21 '11 at 22:53
1
cli.ostream.writeUTF("Teste");

Shouldn't this be containing a new line? Otherwise read method will be waiting for new line I think.

Also as suggested you can try flushing the ostream after writing to it.

Mob
  • 10,958
  • 6
  • 41
  • 58
Ashwinee K Jha
  • 9,187
  • 2
  • 25
  • 19
  • ostream is the output stream. The OP said that the server receives this message correctly. The problem is that the client doesn't receive the answer from the server. – JB Nizet Oct 21 '11 at 22:17
  • I flushed ostream and added a '\n' to my string now, I wasn't doing this before. But the problem continues the same=/ – Thiago Moraes Oct 21 '11 at 22:19
1

writeUTF() doesn't write a line. See the Javadoc. writeUTF() is for use with readUTF(). And Readers are for use with Writers. So change the DataOutputStream to a BufferedWriter and call write() and then newline().

user207421
  • 305,947
  • 44
  • 307
  • 483
  • I believe I understand what you said, but consider that I'm not a native english speaker so I need Unicode support. What would be the combination of classes that would be recommended in my case? – Thiago Moraes Oct 21 '11 at 22:28
  • @ThiagoMoraes I had a typo. Use Readers and Writers and specify the charset. – user207421 Oct 21 '11 at 22:30