2009-10-16 70 views
5

Tôi không phải là lập trình viên Java chút nào. Tôi cố gắng tránh nó bằng mọi giá, nhưng tôi bắt buộc phải sử dụng nó cho một lớp (trong giáo viên yêu cầu chúng tôi sử dụng Socket(), BufferedReader(), PrintWriter() và nhiều thứ khác bao gồm cả phương thức readLine() của BufferedReader():Java, ổ cắm, BufferedReader, và readline treo ... :(

Về cơ bản, đây là vấn đề tôi có. các tài liệu nêu rõ rằng readLine nên trả về một null ở cuối dòng đầu vào, nhưng đó không phải là những gì đang xảy ra.

Socket link  = new Socket(this.address, 80); 
BufferedReader in = new BufferedReader(new InputStreamReader(link.getInputStream())); 
PrintWriter out = new PrintWriter( new PrintWriter(  link.getOutputStream(), true)); 

out.print("GET blah blah blah"); // http request by hand 
out.flush(); // send the get please 

while((s=in.readLine()) != null) { 

    // prints the html correctly, hooray!! 
    System.out.println(s); 
} 

Thay vì kết thúc vào cuối HTML, tôi nhận được một l trống ine, 0 và một dòng trống khác và sau đó in.readLine() treo mãi mãi. Tại sao? Giá trị rỗng của tôi ở đâu?

Tôi đã thử out.close() để xem liệu có thể Yahoo! đang thực hiện một phiên liên tục http hoặc thứ gì đó (mà tôi không nghĩ rằng nó sẽ không có tiêu đề chúng tôi sẵn sàng làm điều đó).

Tất cả các ví dụ về ổ cắm Java mà tôi đang tìm thấy trên mạng dường như chỉ ra khi vòng lặp là biểu mẫu chính xác. Tôi chỉ không biết đủ Java để gỡ lỗi điều này.

Trả lời

8

Sự cố của bạn là mã hóa nội dung “chunked”. Điều này được sử dụng khi độ dài của nội dung được yêu cầu từ máy chủ web không được biết tại thời điểm phản hồi được bắt đầu. Về cơ bản nó bao gồm số byte được gửi, tiếp theo là CRLF, theo sau là các byte. Sự kết thúc của một phản ứng được báo hiệu bởi trình tự chính xác mà bạn đang thấy. Máy chủ web hiện đang chờ yêu cầu tiếp theo của bạn (điều này còn được gọi là "yêu cầu pipelining").

Bạn có một vài khả năng:

  • Sử dụng HTTP phiên bản 1.0. Điều này sẽ khiến máy chủ web tự động đóng kết nối khi một phản hồi đã được gửi hoàn toàn.
  • Chỉ định tiêu đề “Kết nối: đóng” khi gửi yêu cầu của bạn. Điều này cũng sẽ đóng kết nối.
  • Mã hóa nội dung phân tích cú pháp "chẻ" một cách chính xác và chỉ cần xử lý điều này như thể câu trả lời giờ đã hoàn thành — chính xác là như thế nào.
+0

Điều này có ý nghĩa. Tôi cần kiểm tra các tiêu đề. Tôi sẽ sử dụng http1.0. – jettero

+0

Có, cho một bài tập ở trường là điều hợp lý nhất để làm. – Bombe

7

Vì vậy, bạn đang đọc từ một ổ cắm (bạn không thể hiện điều đó trong mã của mình, nhưng đó là những gì tôi thu thập từ văn bản)?

Miễn là bên kia không đóng kết nối, Java không biết rằng nó ở cuối đầu vào, vì vậy readLine() đang đợi phía bên kia gửi nhiều dữ liệu hơn và không trả lại null.

+0

... đọc từ ổ cắm, có. Tôi đã thêm vào câu hỏi đó, cảm ơn. – jettero

4

Hãy thử GET url HTTP/1.0. HTTP/1.0 cho máy chủ biết rằng bạn không thể xử lý nhiều hơn một tài liệu cho mỗi kết nối. Trong trường hợp này, máy chủ sẽ đóng kết nối sau khi gửi kết quả cho bạn.

+0

Vâng, điều đó có ý nghĩa và nó hoạt động.Trong các ngôn ngữ khác tôi chỉ đơn giản sẽ đóng bên cạnh ổ cắm của tôi để máy chủ web biết chỉ có một yêu cầu ... nhưng khi tôi out.close() nó dường như đóng cả hai bên của liên kết. Có cách nào để đóng chính xác một bên không? Tôi có hiểu sai những gì xảy ra không? – jettero

+0

Bạn nói đúng, việc gọi gần 'out' cũng sẽ đóng luồng gửi đến. IIRC, đó là một lỗi/tính năng trong lớp xử lý URL Javas. –

0

Yêu cầu HTTP của bạn không hoàn thành nếu không có 2 cặp trả lại hàng. Có thể bạn cũng nên gọi gần sau khi yêu cầu được gửi:

out.print("GET /index.html HTTP/1.0\r\n"); 
// maybe print optional headers here 
// empty line 
out.print("\r\n"); 
out.flush(); 
out.close(); 
Các vấn đề liên quan