0

I can't figure out why. When the server sends a string to the client, the client gets it just fine. But when I added code to my Client class to send a string to my Server, it doesn't work. Help?

edit: So I deleted the out.close(); in my Server class and replaced it with skt.shutdownOutput(); but now when I call my classes I get:

======================
Server has connected!
Server: Sending message: Test string to show connection between server and client.
Client: Received message: null
Server: Received message: null

Why?

Client Class:

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

class Client {

public static void main(String args[]) {

}

//for receiving messages from Server

public void receiveMessage() {
    try {
        Socket skt = new Socket(InetAddress.getLocalHost().getHostName(), 1234);
        BufferedReader in = new BufferedReader(new InputStreamReader(skt.getInputStream()));
        //while (!in.ready()) {}
        System.out.println("Client: Received message: " + in.readLine()); // Read one line and output it
        in.close();
        //skt.close(); //maybe delete
    } catch (Exception e) {
        System.out.print("Client had error receiving message.\n");
    }
}

//for sending messages to Server
public void sendMessage(String message) throws IOException {
    try {
        Socket skt = new Socket(InetAddress.getLocalHost().getHostName(), 1234);
        PrintWriter pw = new PrintWriter(skt.getOutputStream());
        System.out.println("Client: Sending message: " + message);
        pw.print(message);
        //skt.close(); //maybe delete
    } catch (Exception e) {
        System.out.println(e);
        System.out.print("Client had error sending message.\n");
    }

}
}

Server Class:

import java.lang.*;
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Server {

String message = "Test string to show connection between server and client.";

public void Open() {
    final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
    Runnable serverTask = new Runnable() {

        @Override
        public void run() {
            try {
                System.out.println("Opening...");
                ServerSocket srvr = new ServerSocket(1234);
                while (true) {
                    Socket skt = srvr.accept();
                    clientProcessingPool.submit(new ClientTask(skt));
                }
            } catch (Exception e) {
                System.out.println(e);
                System.out.print("You're opening too many servers in the same location, fool!\n");
            }
        }
    };
    Thread serverThread = new Thread(serverTask);
    serverThread.start();
}

private class ClientTask implements Runnable {

    private final Socket skt;

    private ClientTask(Socket skt) {
        this.skt = skt;
    }

    @Override
    public void run() {
        //for sending messages
        System.out.println("======================");
        System.out.println("Server has connected!");
        PrintWriter out = null;
        try {
            out = new PrintWriter(skt.getOutputStream(), true);
        } catch (IOException ex) {
            System.out.println(ex);
            System.out.println("Server had error sending message.");
        }
        System.out.print("Server: Sending message: " + message + "\n");
        out.print(message);
        //out.close();
        try {
            skt.shutdownOutput();
        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }

        /*
        try {
            skt.close();
        } catch (IOException ex) {
            Logger.getLogger(Server.class.getName()).log(Level.SEVERE, null, ex);
        }*/

        //for receiving messages
        //maybe make message procesing method
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(skt.getInputStream()));
            System.out.println("Server: Received message: " + br.readLine()); // Read one line and output it
            //br.close();
            //skt.close(); //maybe delete
        } catch (Exception e) {
            System.out.println("Server had error receiving message.");
            System.out.println("Error: " + e);
        }

    }
}

}

Thank you for any advice.

2
  • Which of the methods are you calling in the client? Receive or send? Commented Mar 30, 2015 at 18:14
  • Just Receive right now. But initiating SendMessage in the client sends a message from client but no response from server Commented Mar 30, 2015 at 18:22

1 Answer 1

3
    out.print(message);
    out.close();

By closing your PrintStream you are closing the underlying OutputStream.

The documentation of getOutputStream() in Socket says:

Closing the returned OutputStream will close the associated socket.

So when you close your PrintStream, you also close the socket. Close your streams only when you are done with all communications between client and server for the current session.


The next problem you have (after your edit) is that you are not flushing the data. Your client connect, the server prints, without flushing, therefore the data is still waiting in the buffer, not in the stream. Closing a stream as you did previously would also flush the data, but now that you are just throwing the stream away, the data that was not flushed is discarded.

Hence, the stream closes, and the client sees the null that indicates the end-of-stream.

So you need to flush the data before you discard the stream.

And the server is reporting that it has received null because nothing is sent to it on its input stream. The client receives the information and then exits, which causes the socket to close, the streams to close, and the server to see an end-of-stream.

If you call your sendMessage method, you'll see pretty much the same. The stream is writing something but nobody is listening for it. Because the message is short, the server doesn't block writing it, but nobody is reading it on the other side and it has the potential to block. Then, the server tries to read what was sent to it. But your client doesn't flush the data before it completes execution and closes the socket. Thus, the server will also see null.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for you help. So I tried deleting out.close(); but then my program would stall and not continue. Then, with a little googling, I found out that I should use shutdownOutput() on my socket. So when I tried that the sent and received messages for the server became "null". Do you know why this is?
@user3461709 I suggest you edit your question, explain where and what you modified, and what exactly became null that wasn't null before, and then we may be able to answer that.
@user3461709 I edited my answer to follow your edit.
Thank you so much! Works perfectly after adding flush methods to both of the output methods of my classes!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.