我正试图从web浏览器客户端提供的套接字读取输入流。到目前为止,我采取的每一种方法都得到了相同的结果,只是悬而未决,我不知道为什么。我已经尝试过mark()
将读取限制标记为可用内容,但仍然没有成功。
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 rn" + "200 OK").getBytes());
clientOutput.write(("ContentType: " + "text/html" + "rn").getBytes());
clientOutput.write("rn".getBytes());
clientOutput.write("Hello World!".getBytes());
clientOutput.write("rnrn".getBytes());
clientOutput.flush();
inputStream.close();
clientOutput.close();
try{
clientSocket.close();
}catch(Exception ex){
ex.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
任何帮助都将不胜感激!非常感谢。
浏览器建议您应该把这些都扔进垃圾桶并使用HTTP,因为浏览器。
但是,如果你坚持的话,这里有两个问题。
- 你把事情搞得太复杂了
你可以把所有的代码都替换成这行简单的代码:
byte[] bytes = in.readAllBytes();
它替换了以in.mark(in.available())
开头的行(这一行什么都不做,我不知道你是从哪里得到的。如果你认为它应该做一些特定的事情,你可能想提到它。因为它什么也不做。如果你曾经做过reset
,mark
很有用,但你没有,你不需要在这里,因此,没有用(,一直到"byte[]字节=。。。;
- 套接字不会关闭,除非发送方尽力关闭它
您的读取代码(您的,或上面简单得多的一行代码(读取所有内容,直到流关闭。在第二个片段中,您立即关闭它,这显然不起作用。您无法知道何时关闭它,发件人会执行此任务。显然它没有这么做。
我建议您调整预卷大小的协议,这样您就知道要读取多少,而不必仅仅为了发出数据已发送的信号而关闭套接字。
例如:
byte[] sizeRaw = in.readNBytes(4);
int size = ByteBuffer.wrap(bytes).getInt();
byte[] bytes = in.readNBytes(size);
当然,您必须调整发送代码才能首先发送大小(作为32位值,big-endian(。无论如何,你必须在这里查看发送代码。要么修复它,使其在完成后关闭,要么更好的是,调整它,使它先发送大小。