简体   繁体   中英

Networking in Java, 'readLine()' on multiple lines of response in client

I'm currently writing a mail client that simply opens a connection to a mail server and receives the responses from it.

However, when I receive the response from the server, it only works when the response is one line. When the response is more than one line(multiple lines), then it only receives the first line of response.

If I could know the format of response such as there is \\n at the end of each line, it would be easier to format the response. But since I'm only writing a client not the server, I don't know the response format as well.

Below is the code I have written.

public class Main {
private static Socket client;
private static final BufferedReader br
        = new BufferedReader(new InputStreamReader(System.in));

public static void main(String[] args) {
    try {
        /* Input format checking before opening a connection,
            the input must be a form of mail_server and port_number */
        if (args.length != 2)
            System.exit(1);

        /* Set up the connection to mail server from the command line */
        client = new Socket(args[0], Integer.parseInt(args[1]));

        /* Initialize sender that sends message to the server */
        PrintStream sender = new PrintStream(client.getOutputStream());

        /* Initialize receiver that receives message from the server */
        BufferedReader receiver
                = new BufferedReader(
                        new InputStreamReader(client.getInputStream()));

        while (true) {
            /* Flushing buffer */
            String message;

            /* Printing the resulting response from the server */
            while ((message = receiver.readLine()) != null) {
                System.out.println(message);
            }

            /* Get input message from the user */
            message = br.readLine();

            /* If the user inputs "exit", then the program terminates */
            if (message.equals("exit")) System.exit(1);

            /* If not exit, send the message to server */
            sender.println(message);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            client.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

}

I have also tried,

// Assuming that the output format has '\n' at the end of each lines
String[] messages = receiver.readLine().split("\n");

But it only prints out the first line of the response as well.

I have seen very similar question at Java server-client readLine() method but the question has been resolved by editing the server code where I can only change the client code.

Can anyone please suggests me any ideas?

Thanks in advance.

The loop that reads from the server will keep reading until the server signals the end of the stream by closing it. I guess the server is waiting for commands from the client, and the client is waiting for the server to close the stream. So both are stuck.

You need to analyze the messages from the server to determine when the response ends. For example, the LIST command produces a response that looks like this:

+OK 2 messages (320 octets)
1 120
2 200
.

The response is terminated by a line with a single period. The server won't close the stream yet, otherwise it won't be able to respond to future commands.

Hm i got it to work with netcat, eg:

nc -l -p 31337

After starting netcat you can type in some input which will be sent to the client after connecting.

So with netcat it works. I would recommend to use variables just for one purpose.

        while(true){
        /* Flushing buffer */
        String SvMessage;
        while (!receiver.ready()){} //wait for buffer
        /* Printing the resulting response from the server */
        while (receiver.ready()){
            SvMessage = receiver.readLine();
            System.out.println(SvMessage);
        }

        /* Get input message from the user */
        String userMessage = "hello";

        /* If the user inputs "exit", then the program terminates */
        if (userMessage.equals("exit")) System.exit(1);

        /* If not exit, send the message to server */
        sender.print(userMessage + "\r\n");
        }

I made some changes: 1.) changed while condition to br.ready() 2.) instead of PrintStream.println using PrintStream.print(message + "\\r\\n) 3.) not using a BufferedReader for userinput, just sending "commands" (or hello) 4.) added while (!receiver.ready()){} to wait for buffer to fill

So the client will now always reply to the server with new commands (or "hello"). =)

Hope this helps

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