簡體   English   中英

嘗試從 web 瀏覽器 Java 讀取輸入 stream 時,套接字掛起

[英]Socket hangs when trying to read input stream from web browser Java

我正在嘗試從 web 瀏覽器客戶端提供的套接字讀取輸入 stream。 到目前為止,我采取的每種方法都得到了相同的結果,它只是掛起,我不知道為什么。 我已經嘗試使用mark()將讀取限制標記為可用但仍然沒有 go。

inputStream.mark(inputStream.available());

ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 9];
int read;

while((read = inputStream.read(buffer)) > 0) {
    outputStream.write(buffer, 0, read);
}
byte[] bytes = outputStream.toByteArray();

我也嘗試過clientSocket.shutdownInput()來嘗試解決這個問題,但還是不行。

以下是我的嘗試:

import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class Server {
    public static void main(String[] args)
    {
        ServerSocket server = null;

        try {

            // Server is listening on port 3001
            server = new ServerSocket(3001, 1, InetAddress.getByName("localhost"));
            server.setReuseAddress(true);

            // running infinite loop for getting
            // client request
            while (true) {

                // socket object to receive incoming client
                // requests
                Socket client = server.accept();

                // Displaying that new client is connected
                // to Server
                System.out.println("New client connected"
                        + client.getInetAddress()
                        .getHostAddress());


                // create a new thread object
                ClientHandler clientSock
                        = new ClientHandler(client);

                // This thread will handle the client
                // separately
                new Thread(clientSock).start();

            }
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    // ClientHandler class
    private static class ClientHandler implements Runnable {

        private final Socket clientSocket;

        // Constructor
        public ClientHandler(Socket clientSocket)
        {
            this.clientSocket = clientSocket;
        }

        public void run() {


            InputStream inputStream = null;
            OutputStream clientOutput = null;
            try {

                inputStream = clientSocket.getInputStream();
                inputStream.mark(inputStream.available());

                clientSocket.shutdownInput();

                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                byte[] buffer = new byte[1024 * 9];
                int numRead;

                while((numRead = inputStream.read(buffer)) > 0) {
                    outputStream.write(buffer, 0, numRead);
                }

                byte[] bytes = outputStream.toByteArray();

                String payloadString = new String(bytes, StandardCharsets.UTF_8);
                System.out.println(payloadString);

                clientOutput = clientSocket.getOutputStream();
                clientOutput.write(("HTTP/1.1 \r\n" + "200 OK").getBytes());
                clientOutput.write(("ContentType: " + "text/html" + "\r\n").getBytes());
                clientOutput.write("\r\n".getBytes());
                clientOutput.write("Hello World!".getBytes());
                clientOutput.write("\r\n\r\n".getBytes());
                clientOutput.flush();
                inputStream.close();
                clientOutput.close();
                try{
                    clientSocket.close();
                }catch(Exception ex){
                    ex.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

非常感激任何的幫助。 謝謝你。

browsers 建議您應該將所有這些都扔進垃圾箱並使用 HTTP,因為,嗯,瀏覽器。

但是,如果你堅持,這里有兩個問題。

  1. 你把事情搞的很復雜。

您可以使用所有這些代碼並將其全部替換為以下簡單的小行:

byte[] bytes = in.readAllBytes();

這取代了以in.mark(in.available())開頭的行(這條線什么都不做,我不知道你從哪里得到的。如果你認為它應該做一些特定的事情,你可能想提一下那。因為它什么也沒做。如果你曾經resetmark是有用的,你不是,你不需要在這里,因此,沒用),一直到`byte [] bytes =.. .;

  1. sockets 不會關閉,除非發件人竭盡全力關閉它

您的讀取代碼(您的,或者上面更簡單的單行代碼)讀取所有內容,直到 stream 關閉。 在您的第二個片段中,您立即將其關閉,這顯然不起作用。 知道什么時候關閉它,發件人完成這項工作。 顯然它沒有這樣做。

我建議您調整預滾動大小的協議,這樣您就知道要讀取多少,而不是僅僅依靠關閉套接字來發出數據已發送的信號。

例如:

byte[] sizeRaw = in.readNBytes(4);
int size = ByteBuffer.wrap(bytes).getInt();
byte[] bytes = in.readNBytes(size);

您當然必須調整發送代碼以首先發送大小(作為 32 位值,大端)。 您必須以一種或另一種方式查看此處的發送代碼。 要么修復它,讓它在完成后關閉,或者更好的是,調整它,讓它首先發送大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM