请求响应消息不同步未预期的行为

时间:2012-03-19 19:18:49

标签: java client-server

客户

import java.io.*;
import java.net.*;
import java.util.Scanner;

public class HTCPCPClient {

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

        HTCPCPClient client = new HTCPCPClient();
        System.out.println("WELCOME TO THE COFFEE POT APPLICATION!");
        client.startClient();
    }

    private void startClient() throws IOException {
        final String HOST = "localhost";
        final int PORT_NUMBER = 4444;
        Socket clientSocket = null;
        PrintWriter outToServer = null;
        BufferedReader in = null;
        String serverSentence = null;
        String clientSentence = null;
        BufferedReader inFromServer = null;

        // create new socket
        clientSocket = new Socket(HOST, PORT_NUMBER);
        outToServer = new PrintWriter(clientSocket.getOutputStream(), true);
        in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

        do {  // wait for 'QUIT'              
            // Create input stream
            inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

             kbd = new Scanner(System.in);
             clientSentence = null;
             kbdInput = null;

                System.out.println("Enter Method ( e.g. BREW )");
                // next line of kbdInput from keybd.

                kbdInput = kbd.nextLine().trim();

                clientSentence = kbdInput + " coffee://127.0.0.1/pot-1 HTCPCP-new Accept-Additions: ";
                clientSentence = clientSentence + "\nstart\n@@";     

            // Send clientSentence to server
            outToServer.println(clientSentence);
            outToServer.flush();

            System.out.println("\nMESSAGE FROM SERVER:");

            do {
                serverSentence = inFromServer.readLine();
                System.out.println("\t" + serverSentence);

                if (serverSentence.equals("@@") == true) {
                    break;
                }
            } while (true);
            // read and print message from server

        } while (!clientSentence.contains("QUIT"));

        // close connections 
        outToServer.close();
        in.close();
        inFromServer.close();
        clientSocket.close();
    } 

}

服务器线程

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

public class HTCPCPClientWorker extends Thread {

    Socket cwsocket = null;

    public HTCPCPClientWorker(Socket cwsocket) {
        super("ClientWorker");
        this.cwsocket = cwsocket;
    }

    @Override
    public void run() {

        String clientSentence = null;
        BufferedReader inFromClient = null;
        PrintWriter outToClient = null;

        try {
            inFromClient = new BufferedReader(new InputStreamReader(cwsocket.getInputStream()));
            outToClient = new PrintWriter(cwsocket.getOutputStream(), true);
        } catch (IOException ex) {
            System.err.println("Cannot create streams");
        }

        try {

            do { // end when client says QUIT

                StringBuffer clientInputLine[] = new StringBuffer[3];

                clientInputLine[0] = new StringBuffer();
                clientInputLine[1] = new StringBuffer();

                // Get next message from client 
                for (int i = 0; i <= clientInputLine.length; i++) {

                    // read input line from BufferedReader 
                    clientSentence = inFromClient.readLine();

                    // wait for EOF = @@ 
                    System.out.println("\tInput: " + clientSentence);
                    if (clientSentence.equals("@@") == true) {
                        break;
                    }
                    clientInputLine[i].append(clientSentence);


                    if (clientSentence.contains("BREW")) {
                        outToClient.println("Message: " + clientSentence);
                        outToClient.println("HTCPCP-new 200 OK BREW START command completed.");
                        outToClient.println("Content-length:  " + clientSentence.length()); 
                        outToClient.println("@@");
                        outToClient.flush();
                    } else {
                        outToClient.println("Message: " + clientSentence);
                        outToClient.println("HTCPCP-new 400 Bad Request.");
                        outToClient.println("Content-length:  " + clientSentence.length()); 
                        outToClient.println("@@");
                        outToClient.flush();
                    }


                } // end for loop


            } while (!clientSentence.contains("QUIT"));

            outToClient.println("GOODBYE!");
            outToClient.flush();

            System.out.println("\tClient has disconnected.");
            cwsocket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    } // end run

} end HTCPCPClientWorker.java

客户端控制台

WELCOME TO THE COFFEE POT APPLICATION!

Select an option:
1. Brew
2. Quit
1
Enter URL (e.g. BREW coffee://127.0.0.1/pot-1 HTCPCP-new )
BREW

MESSAGE FROM SERVER:
    Message: BREW Accept-Additions: 
    HTCPCP-new 200 OK BREW START command completed.
    Content-length:  23
    @@

Select an option:
1. Brew
2. Quit
1
Enter URL (e.g. BREW coffee://127.0.0.1/pot-1 HTCPCP-new )
BREW

MESSAGE FROM SERVER:
    Message: start
    HTCPCP-new 400 Bad Request.
    Content-length:  5
    @@

Select an option:
1. Brew
2. Quit

请注意,尽管输入了相同的URL,但来自服务器的消息也不同。

我出错的任何想法?

1 个答案:

答案 0 :(得分:1)

在您的服务器中,您已经在循环的每次迭代中得到了这个:

if (clientSentence.contains("BREW")) {
    outToClient.println("Message: " + clientSentence);
    outToClient.println("HTCPCP-new 200 OK BREW START command completed.");
    outToClient.println("Content-length:  " + clientSentence.length()); 
    outToClient.println("@@");
    outToClient.flush();
} else {
    outToClient.println("Message: " + clientSentence);
    outToClient.println("HTCPCP-new 400 Bad Request.");
    outToClient.println("Content-length:  " + clientSentence.length()); 
    outToClient.println("@@");
    outToClient.flush();
}

因此服务器将读取“BREW”(等),然后吐出所有输出,以@@结尾。您的客户端显示所有这些,然后请求下一个输入...但服务器将不会完成发送,因为它将读取 next 输入行,即“start” 。然后打印出第二个响应,即使它仍在读取第一个请求。

我建议您完成阅读请求然后写出回复...

请注意,您的输入循环也应该具有独占上限:

for (int i = 0; i <= clientInputLine.length; i++) {
    ...
    // This will blow up if i == clientInputLine.length
    clientInputLine[i].append(clientSentence);