2017-04-10 70 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