2017-04-10 66 views
0

我想实现一个POP3客户端。我知道在POP3协议中,每条消息以\r\n结尾。我想用Java编写一个recvuntil方法,它将能够一次接收完整的消息。直到 r n在Java中

超级容易在Python:

def recv_all_until_ver3(s, crlf): 
    data = "" 
    while data[-len(crlf):] != crlf: 
     data += s.recv(1) 
    return data 

然而,当我试图做同样在Java中:

class JavaApplication1 { 

    /** 
    * @param args the command line arguments 
    */ 
    public static void main(String[] args) throws IOException { 
     // TODO code application logic here 
     String serverAddress = "interia.pl"; 
     int port = 110; 

     Socket s = new Socket(serverAddress, port); 
     BufferedReader input = new BufferedReader(new InputStreamReader(s.getInputStream())); 
     String answer = ""; 
     while (!answer.contains("\r\n")) { 
      answer = input.readLine(); 
      System.out.println(answer); 
     } 
    } 
} 

它接收一个消息,而不是手结束本身。有什么办法可以在Java中实现这个方法吗?我可以直接阅读字符,而不是整行,直到我在邮件中找到\r\n?谢谢。

+0

您可以https://docs.oracle.com/javase/8/docs/api/java/io/BufferedReader.html#read-- – Fildor

回答

0

您可以使用Scanner类(它接受InputStream作为构造函数参数),并使用useDelimiter方法设置分隔符。读取与\r\n

1

的Python代码读取一次在一个八位位组结束的消息,立即将其追加到answer,并且如果在当前迭代answerCRLF结束它的完成信号。

Java代码挂起,因为BufferedReader.readLine()返回剥离行终止后的行内容。此时answer不包含CRLF,因此readLine()被再次调用,并且由于流不会从另一端关闭(程序会抛出一个NullPointerException),并且您有无限的读取超时(您会看到一个SocketTimeoutException) ,它挂起,永远等待下一行。

正确的版本是

Socket socket = connect(); // Implement this 
Scanner scanner = new Scanner(new InputStreamReader(socket.getInputStream(), "ASCII")); 
scanner.useDelimiter("\r\n"); 
String response = scanner.nextLine(); 
socket.close(); 

注:

+0

OK,我想这读单字符/gist.github.com/anonymous/b227b9907f6764bcdca3a856787a0b1f。我的新主题:http://stackoverflow.com/questions/43350870/imap-client-in-java-sockets-only-hangs-on-receiving。但它似乎不起作用。 – mirx

+0

Noooo!你不需要循环!它是'Scanner.nextLine()'循环直到找到行终止。只需复制,粘贴和研究提供样本;-) – Raffaele

+0

精细,但这并不工作太:(https://gist.github.com/anonymous/084a6a6b66d4e7455e19802e6ae83819。接收到第一消息后仍然挂起,这在某种程度上着接收第二个。 – mirx