Unable to stream to browser

I just wrote a small program to test something, as shown below:

public class Main { public static void main(String[] args){ ServerSocket serverSocket = null; Socket clientSocket = null; DataInputStream dataInputStream= null; BufferedWriter bufferedWriter = null; String line ; try { serverSocket = new ServerSocket(80); clientSocket = serverSocket.accept(); dataInputStream = new DataInputStream(clientSocket.getInputStream()); while((line = dataInputStream.readLine()) != null){ System.out.println(line); } bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); bufferedWriter.write("HTTP/1.0 200 OK \n Date: Fri, 31 Dec 1999 23:59:59 GMT \n Content-Type: text/html \n Content-Length: 1354 \n <html>abcde<html/>"); bufferedWriter.flush(); } catch (IOException e) { System.out.println("socket port cannot be opened."); e.printStackTrace(); } finally{ try { serverSocket.close(); bufferedWriter.close(); } catch (IOException e) { System.out.println("socket port cannot be closed."); e.printStackTrace(); } } } } 

I found the http response format from the internet, it should be correct. The problem is that my browser continues to wait for response data (determine from the rotating logo), but the data does not return successfully. What mistake did I make?

I connect to the Java program by typing โ€œlocalhostโ€ in the browser, I can print the query string in the Java program, but I just canโ€™t send a response.

+6
source share
3 answers

Firstly, there are several problems with the sent HTTP message: each line of the HTTP message is split / ends with CR LF, and not just a line feed (although I doubt this could be a problem, you should replace "\ n" with "\ r \ n "). In addition, the Content-Length is not equal to the actual size of the message body to be replaced. Before the actual body, all HTTP messages should have an empty string that you do not have. Finally, the forward slash in <html/> should also appear before html , for example: </html>

Summarizing:

 bufferedWriter.write("HTTP/1.0 200 OK\r\nDate: Fri, 31 Dec 1999 23:59:59 GMT\r\nContent-Type: text/html\r\nContent-Length:18\r\n\r\n<html>abcde</html>"); 

Now for the real problem: the read loop was constantly expecting more data. Comparing the readLine () result with zero does not actually do what you were looking for. TCP connections create data streams, and you never know if the client simply stopped sending data at a certain point. Instead, you can read until you find a blank line that marks the end of the header of the HTTP message. Web browsers usually do not send additional content to GET messages, so you will not be missing any data.

  BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); while(!(line = reader.readLine()).isEmpty()){ System.out.println(line); } 
+3
source

Can this header field be Content-Length? Try replacing the answer as follows:

 bufferedWriter.write("HTTP/1.0 200 OK \n Date: Fri, 31 Dec 1999 23:59:59 GMT \n Content-Type: text/html \n Content-Length: 18\n <html>abcde<html/>"); 

(Pay attention to Content-Length: 18 compared to the original Content-Length: 1354 )

I suspect the browser is waiting for your application to send more data.

Edit: this works for me:

 import java.util.*; import java.io.*; import java.net.*; public class Main { public static void main(String[] args) throws Exception{ ServerSocket serverSocket = null; Socket clientSocket = null; DataInputStream dataInputStream= null; BufferedWriter bufferedWriter = null; try { serverSocket = new ServerSocket(8080); clientSocket = serverSocket.accept(); BufferedReader reader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); while (clientSocket.getInputStream().available() > 0) { String line = reader.readLine(); if (line == null) { break; } System.out.println(line); } bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); bufferedWriter.write("HTTP/1.0 200 OK \n Date: Fri, 31 Dec 1999 23:59:59 GMT \n Content-Type: text/html \n\n <html>abcde<html/>"); bufferedWriter.flush(); clientSocket.close(); } catch (IOException e) { System.out.println("socket port cannot be opened."); e.printStackTrace(); } finally{ try { serverSocket.close(); bufferedWriter.close(); } catch (IOException e) { System.out.println("socket port cannot be closed."); e.printStackTrace(); } } } } 

The culprit was the while loop. The method that you called to obtain additional data was blocked until this data was available (which will never be). I'm not sure if what I did was absolutely necessary, but it works.

+3
source

I see two problems:

The content length header is 1354 bytes. You write only 20 or so. Content length is optional; do not enable it if you are not using the correct value.

You need an empty line at the end of the headers and before the content: ".... Content-Length: xx\n\n<html>..."

+1
source

Source: https://habr.com/ru/post/922070/


All Articles