Java网络和#x27;readLine()';在客户端的多行响应上
我目前正在编写一个邮件客户端,它只需打开与邮件服务器的连接并从中接收响应 但是,当我从服务器收到响应时,它仅在响应为一行时工作。当响应不止一行(多行)时,它只接收第一行响应 如果我可以知道响应的格式,例如每行末尾有\n,则设置响应的格式会更容易。但由于我只编写客户端而不是服务器,所以我也不知道响应格式 下面是我写的代码Java网络和#x27;readLine()';在客户端的多行响应上,java,networking,Java,Networking,我目前正在编写一个邮件客户端,它只需打开与邮件服务器的连接并从中接收响应 但是,当我从服务器收到响应时,它仅在响应为一行时工作。当响应不止一行(多行)时,它只接收第一行响应 如果我可以知道响应的格式,例如每行末尾有\n,则设置响应的格式会更容易。但由于我只编写客户端而不是服务器,所以我也不知道响应格式 下面是我写的代码 public class Main { private static Socket client; private static final BufferedReader br
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();
}
}
}
}
我也试过,
// Assuming that the output format has '\n' at the end of each lines
String[] messages = receiver.readLine().split("\n");
但它也只打印出响应的第一行
我在上看到了非常类似的问题,但问题已经通过编辑服务器代码得到了解决,我只能更改客户端代码
谁能给我一些建议吗
提前感谢。从服务器读取的循环将继续读取,直到服务器通过关闭它发出流结束的信号。我猜服务器正在等待来自客户端的命令,客户端正在等待服务器关闭流。所以两者都被卡住了 您需要分析来自服务器的消息,以确定响应何时结束。例如,
LIST
命令生成如下响应:
+OK 2消息(320个八位字节)
1 120
2 200
.
响应由一个单周期的行终止。服务器还不会关闭流,否则它将无法响应未来的命令。从服务器读取的循环将继续读取,直到服务器通过关闭流来发出流结束的信号。我猜服务器正在等待来自客户端的命令,客户端正在等待服务器关闭流。所以两者都被卡住了 您需要分析来自服务器的消息,以确定响应何时结束。例如,
LIST
命令生成如下响应:
+OK 2消息(320个八位字节)
1 120
2 200
.
响应由一个单周期的行终止。服务器还不会关闭流,否则它将无法响应未来的命令。Hm我让它与netcat一起工作,例如:
nc -l -p 31337
启动netcat后,您可以键入一些输入,这些输入将在连接后发送到客户端
因此,对于netcat,它是有效的。我建议只为一个目的使用变量
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");
}
我做了一些改变:
1.)将条件更改为br.ready()
2.)使用PrintStream.print(消息+“\r\n)代替PrintStream.println
3.)不使用BufferedReader进行用户输入,只发送“命令”(或hello)
4.)在(!receiver.ready()){}等待缓冲区填充时添加
因此,客户端现在将始终使用新命令(或“hello”)回复服务器
希望这有助于Hm我将其用于netcat,例如:
nc -l -p 31337
启动netcat后,您可以键入一些输入,这些输入将在连接后发送到客户端
所以netcat是可行的。我建议只为一个目的使用变量
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");
}
我做了一些改变:
1.)将条件更改为br.ready()
2.)使用PrintStream.print(消息+“\r\n)代替PrintStream.println
3.)不使用BufferedReader进行用户输入,只发送“命令”(或hello)
4.)在(!receiver.ready()){}等待缓冲区填充时添加
因此,客户端现在将始终使用新命令(或“hello”)回复服务器
希望这能有所帮助我认为主循环类似于“在检索新邮件时”,因此对套接字的读写是在主循环内完成的。你也可以读写一次@jsh114是这样吗?@Lord_Pedantestein非常感谢,这段代码工作得非常完美。虽然我接受了您的第一个和第四个更改,但并不是全部。@jsh114 u欢迎您。当然,这取决于你如何处理。。关于第4点,我选择“\r\n”是因为它在Linux和Windows上工作得最好(到目前为止:p),有很多可能表示换行符,例如,它可能会导致奇怪的问题。啊,我差点忘了这一点:-祝福^^我认为主循环类似于“在检索新邮件时”,所以对套接字的读写是在主循环内完成的。你也可以读写一次@jsh114是这样吗?@Lord_Pedantestein非常感谢,这段代码工作得非常完美。虽然我接受了您的第一个和第四个更改,但并不是全部。@jsh114 u欢迎您。当然,这取决于你如何处理。。关于第4点,我选择“\r\n”是因为它在Linux和Windows上工作得最好(到目前为止:p),有很多可能表示换行符,例如,它可能会导致奇怪的问题。啊,我差点忘了这一点:-祝福^^从套接字读取的部分看起来不错(但是从用户读取输入的代码只读取一行)。您确定服务器正在发送多条线路吗?如果您有服务器的代码,发布它会很有帮助。@tom我正在使用一家公司的邮件服务器,因此无法访问服务器代码。我确信服务器正在为特定的用户输入发送多行数据(因为我用C++完成了相同的任务),例如“LIST”和“RETR”,其中#是任意整数。此外,用户输入不能超过一行,因为它只包含简单的pop3命令。外部
while(true)
循环没有意义。一旦您从readLine()
中获得空值,就是这样:将不再有任何数据。这段代码将在流的末尾无意识地旋转。移除外部循环。从套接字读取的部分看起来不错(但是从用户读取输入的代码只读取一行)。您确定服务器正在发送多条线路吗?如果您有服务器的代码,发布它会很有帮助。@tom我正在使用一家公司的邮件服务器,所以我可以