[英]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,因为,嗯,浏览器。
但是,如果你坚持,这里有两个问题。
您可以使用所有这些代码并将其全部替换为以下简单的小行:
byte[] bytes = in.readAllBytes();
这取代了以in.mark(in.available())
开头的行(这条线什么都不做,我不知道你从哪里得到的。如果你认为它应该做一些特定的事情,你可能想提一下那。因为它什么也没做。如果你曾经reset
, mark
是有用的,你不是,你不需要在这里,因此,没用),一直到`byte [] bytes =.. .;
您的读取代码(您的,或者上面更简单的单行代码)读取所有内容,直到 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.