gpt4 book ai didi

java - 如何修复 Broken Pipe Socket 异常 (Java)?连接在哪里被关闭?

转载 作者:行者123 更新时间:2023-12-01 22:18:00 24 4
gpt4 key购买 nike

我正在为一个学校项目开发一个多线程网络服务器。我应该能够在浏览器上进入本地主机并请求 3 个不同的文件(.htm、.jpeg、.pdf)。但是,当我对其中包含图片的 .htm 文件执行此操作(2 个请求)时,.htm 文件会出现在浏览器中,但对于我尝试在图片上执行的每次写入,都会出现许多损坏的管道套接字异常(分配需要一次写入 1024 个字节)。我实现此方法的方式明显有问题,但当我尝试写入第二个文件时,我不知道连接在哪里关闭?

我尝试了一些不同的方法来尝试解决此问题,包括尝试读取套接字输入流时的循环,但我认为这违背了多线程服务器的目的。

服务器:

    while(true){
try {
sock = servSock.accept(); // Handles the connection
// Connection received log
System.out.println("Connection received: " + new Date().toString() + " at " + sock.getInetAddress() + sock.getPort());
HTTP pro = new HTTP(sock); // Client handler
pro.run();

ServerThread serverThread = new ServerThread(pro);
// Starts ServerThread
serverThread.start();
} catch (Exception e){
System.out.println(e);
}
}

HTTP:


public void run(){
// Try to open reader
try{
readSock = new BufferedReader(new InputStreamReader(sock.getInputStream()));
} catch (Exception e){
System.out.println(e);
}

// Open output stream
try{
this.out = new DataOutputStream(sock.getOutputStream());
this.printOut = new PrintWriter(sock.getOutputStream());
} catch (Exception e){
System.out.println(e);
}

// Try to read incoming line
try {
this.reqMes = readSock.readLine();
} catch (IOException e) {
e.printStackTrace();
}

StringTokenizer st = new StringTokenizer(reqMes);

// Parse the request message
int count = 0;
while(st.hasMoreTokens()){
String str = st.nextToken();
if (count == 1){
this.fileName = "." + str;
}
count += 1;
}
System.out.println("File name received.");

File file = null;
try {
file = new File(this.fileName);
this.f = new FileInputStream(file); // File input stream
this.fileExists = true;
System.out.println("File " + this.fileName + " exists.");
} catch (FileNotFoundException e) {
System.out.println(e);
this.fileExists = false;
System.out.println("File does not exist.");
}

byte[] buffer = new byte[1024];
// Write status line
if (this.fileExists) {
System.out.println("Trying to write data");
try{
this.out.writeBytes("HTTP/1.0 " + "200 OK " + this.CRLF);
this.out.flush();
this.printOut.println("HTTP/1.0 " + "200 OK " + this.CRLF);
// Write Header
this.out.writeBytes("Content-type: " + getMime(this.fileName) + this.CRLF);
this.printOut.println("Content-type: " + getMime(this.fileName) + this.CRLF);
this.out.flush();

// Read file data
byte[] fileData = new byte[1024];

while (this.f.read(fileData) != -1) {
// Write File data
try{
this.out.write(fileData,0,1024);
this.out.flush(); // Flush output stream
} catch (IOException e) {
System.out.println(e);
}
}
System.out.println("Flushed");
} catch (IOException e) {
e.printStackTrace();
}
}

对于浏览器中的一个 .htm 文件,该文件和 html 看起来都很好。但看起来它在 html 文件中对 .jpeg 文件发出了第二个请求,并且浏览器在每次写入数据时都卡住了 java.net.SocketException: Broken pipeline (Write failed) 加载

this.out.write(fileData,0,1024);

谢谢,非常感谢您的帮助。

最佳答案

经过对不同问题的大量搜索,我找到了答案 here .

问题在于响应 header 格式不正确,导致连接过早结束。 必须在 header 之后发送另一个空行(“\r\n”)。

以下代码现在可以运行(this.CRLF 等于“\r\n”):

    public void run(){
// Try to open reader
try{
readSock = new BufferedReader(new InputStreamReader(sock.getInputStream()));
} catch (Exception e){
System.out.println(e);
}

// Open output stream
try{
this.out = new DataOutputStream(sock.getOutputStream()); // Data output
this.printOut = new PrintWriter(sock.getOutputStream()); // Print output
} catch (Exception e){
System.out.println(e);
}

// Try to read incoming line
try {
this.reqMes = readSock.readLine();
} catch (IOException e) {
e.printStackTrace();
}

StringTokenizer st = new StringTokenizer(reqMes);

// Parse the request message
int count = 0;
while(st.hasMoreTokens()){
String str = st.nextToken();
if (count == 1){
this.fileName = "." + str;
}
count += 1;
}
System.out.println("File name received.");

// Initialize file to be sent
File file = null;
// Try to find file and create input stream
try {
file = new File(this.fileName);
this.f = new FileInputStream(file); // File input stream
this.fileExists = true;
System.out.println("File " + this.fileName + " exists.");
} catch (FileNotFoundException e) {
System.out.println(e);
this.fileExists = false;
System.out.println("File does not exist.");
}

byte[] buffer = new byte[1024];
// Write status line
if (this.fileExists) {
System.out.println("Trying to write data");
try{
this.out.writeBytes("HTTP/1.0 " + "200 OK " + this.CRLF);
this.out.flush();
// Write Header
this.out.writeBytes("Content-type: " + getMime(this.fileName) + this.CRLF);
this.out.flush();
this.out.writeBytes(this.CRLF);
this.out.flush();

// Read file data
byte[] fileData = new byte[1024];

int i;
while ((i = this.f.read(fileData)) > 0) {
// Write File data
try{
this.out.write(fileData,0, i);
} catch (IOException e) {
System.out.println(e);
}
}
this.out.flush(); // Flush output stream
System.out.println("Flushed");
closeSock(); // Closes socket
} catch (IOException e) {
e.printStackTrace();
}

关于java - 如何修复 Broken Pipe Socket 异常 (Java)?连接在哪里被关闭?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58612779/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com