简体   繁体   中英

Why does my server PrintWriter.println() fail to send its message over a socket?

I know what you are going to say "use .flush()"....I am. What I have done is build a program that will synchronize 3 machines based on the messages sent from the client.

Here is the algorithm I am using:

  • Connect all client machines to 1 server machine
  • Each client machine gets to the point where it is ready to execute (this is the "syncing" part" so it sends a "ready" flag to the server)
  • Once all machines have sent the "ready" flag via socket, the server sends back "execute" via PrintWriter and the client machines and they execute and finish that iteration
  • After the client has finished executing it sends a "reset" flag back to the server and the server gets ready to start all over (the server doesn't care how many times this will happen)
  • Each client then moves on to the next iteration to do the same exact thing, gets "ready", and then when all are "ready", server sends "execute" again <- this is were the problem is. My Printwriter.println("execute") is supposedly sent but is NEVER received on any of the client machines.

Just to reiteration and be clear, the first time this proccess is carried out, everything go's as expected, on the second iteration, the "execute" command is never sent to the client even though it executes the out.println("execute) line.

Am I doing something wrong? I have also tried PrintStream and see the same problem ever time. Am I handling the BufferedReader wrong? For the life of me I cannot understand why everything works as expected the first time around but then after the second time "execute" is never sent to the client machines. Any help will be much appreciated.

Server snipit:

StartServerResponseThread() Is called after server has accepted the client.

// Init the nuc client
public void NucClientInit(Socket s) {
    new Thread() {
        public void run() {
            try {
                socket = s;
                bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                //out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                //        socket.getOutputStream(), "UTF-8")), true);
                brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
                // Start the reponse thread
                StartServerResponseThread();
                // Confirm connection to client
                ConfirmConnection();
            } catch (IOException ex) {
                Logger.Log("Nuc:NucClientInit:IOException:ex: " + ex);
            }
        }
    }.start();

}

// Sends connect and waits for reponse back from server
private void ConfirmConnection() {
    Logger.Log("Sending connect to: " + ip_address);
    try {
        bufOut.write("connect");
        bufOut.newLine();
        bufOut.flush();
    } catch (IOException ex) {
        Logger.Log("Nuc:ConfirmConnection():bufOut:ex " + ex);
    }
    Logger.Log("Sent connect: " + ip_address);
    while (!connected) {

    }
    Logger.Log(ip_address + " Client is successfully Connected!");
}

// Handles any message from server
private void HandleClientMessage(String message) {
    switch (message) {
        case "connect":
            // Flag connection to confirm client connected (see ConfirmConnection())
            connected = true;
            break;
        case "ready":
            Logger.Log("Nuc:" + ip_address + ":received:ready");
            // Nuc is ready for sync now
            SetNucIsReady(true);
            break;
        case "reset":
            // Nuc has finished test (probably interleave)
            SetNucIsReady(false);
            break;
        default:
            Logger.Log("UNHANDLED CLIENT RSPONSE!!");
    }
}

// Will always run in a separate thread waiting for any response
// from the server
private void StartServerResponseThread() {
    new Thread() {
        public void run() {
            try {
                while ((fromClient = brffReadIn.readLine()) != null) {
                    HandleClientMessage(fromClient);
                }
            } catch (IOException ex) {
                Logger.Log("Nuc:StartServerResponseThread():IOException:ex: " + ex);
            }
        } // Close run()
    }.start();
}

// This method is used to send the execute command to the Nuc machine tied
// to this object.
public void Execute() {

    try {
        bufOut.write("execute");
        bufOut.newLine();
        bufOut.flush();
        Logger.Log(("Class:Nuc:method:Execute:" + ip_address + " sent "
                + "execute command"));
    } catch (IOException ex) {
        Logger.Log("Nuc:Execute():IOException:ex: " + ex);
    }
}

Client:

    // Tell Server ready to execute
static void SendReady(){

    try {
        bufOut.write("ready");
        bufOut.newLine();
        bufOut.flush();
    } catch (IOException ex) {
        log("KPI_Socket:SendReady():bufOut:ex " + ex);
    }   
    log("Sent to Server 'ready'");
}
// Wait until execute is received from server
static void WaitForExecute(){
    log("Waiting for execute command from server");
    while(!execute){

    }
    log("Execute received from Server!");
    execute = false;
}   
// Tell server nuc needs to reset its isReady boolean
static void SendServerReset(){
    try {
        bufOut.write("reset");
        bufOut.newLine();
        bufOut.flush();
    } catch (IOException ex) {
        log("KPI_Socket:SendServerReset():bufOut:ex " + ex);
    }   
    log("Sent to Server 'reset'");
}
// Inform user connection is good
static void HandleConnect(){
    connected = true;
    log("Client Now Connected To Server");
}
// Handles any response from the server
static void HandleServerResponse(String serverResponse){
    switch (serverResponse){
        case "connect":
            HandleConnect();
            break;
        case "execute":
            execute = true;
            HandleExecute();
        default:
            log("UHANDLED RSPONSE FROM SERVER!!")

    }
}
// Will always run in a separate thread waiting for any response
// from the server
static void StartServerResponseThread(){
    new Thread(){
        public void run(){
            while ((fromServer = brffReadIn.readLine()) != null) {
                log("Message from Server: '" + fromServer + "'");
                HandleServerResponse(fromServer);
            }
            log("StartServerResponseThread() CLOSED!!!!!!!!");
        } // Close run()
    }.start();
}
// Init all components, connect to server and start server response thread
static void ConnectToServer(String host, int port){
    hostname = host;
    portNumber = port;
    try {

        log("Attempting to connect to " + hostname + "\n");
        socket = new Socket(hostname, portNumber);
        log("Connected to " + hostname);

        bufOut = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        //out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
          //              socket.getOutputStream(), "UTF-8")), true);
        brffReadIn = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
        // Start the server response thread to run in background
        StartServerResponseThread();
        // Wait for response from server on connect message
        while(!connected){
            log("Waiting for greeting message from server");
            wait_for(1);
        }
        try {
            bufOut.write("connect");
            bufOut.newLine();
            bufOut.flush();
        } catch (IOException ex) {
            log("KPI_Socket:ConnectToServer():bufOut:ex " + ex);
        }
    } catch (UnknownHostException e) {
        log("KPI_Socket:ConnectToServer():UnknownHostException" + e);
    } catch (IOException e) {
        log("KPI_Socket:ConnectToServer():IOException: " + e);
    }
} // Close ConnectToServer();

I know what you are going to say "use .flush()"...

No I'm not. I'm going to say 'don't use PrintWriter '. It swallows exceptions. Use BufferedWriter , write() , newline() , and flush() . That way if there are any exceptions, you'll see them. With PrintWriter , you can't.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM