我正在尝试制作Java TCP Multithread Server,该服务器允许您制作“ GET”和“ HEAD”。问题是即使正确发送HEAD,发送的文件也不会加载到浏览器上。
Js代码:
ServerTCP.java
package ServerTCP;
import java.net.*;
import java.io.*;
public class ServerTCP{
public static void main(String argv[]) throws IOException {
if (argv.length != 1) {
System.err.println("Format: ServerTCP <port>");
System.exit(-1);
}
Socket connectionSocket = null;
try{
// Create a server socket
int port = Integer.parseInt(argv[0]);
ServerSocket server = new ServerSocket(port);
// Set a timeout of 300 secs
server.setSoTimeout(300000);
while(true){
// Esperamos posibles conexiones
connectionSocket = server.accept();
// Creamos un objeto ThreadServidor, pasándole la nueva conexión
ThreadServer handler = new ThreadServer(connectionSocket);
// Iniciamos su ejecución con el método start()
handler.start();
}
}catch(SocketTimeoutException e){
System.err.println("Nothing received in 300 secs");
}catch(IOException | NumberFormatException e){
System.err.println("Error: " + e.getMessage());
}finally{
if(connectionSocket != null)
connectionSocket.close();
}
}
}
ThreadServer.java
package ServerTCP;
import java.net.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.time.format.DateTimeFormatter;
import java.time.LocalDateTime;
import java.time.ZoneId;
public class ThreadServer extends Thread {
Socket socket;
public ThreadServer(Socket s) {
// Almacenamos el socket de la conexión
this.socket = s;
}
@SuppressWarnings("override")
public void run() {
try {
// Establecemos el canal de entrada
BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// Establecemos el canal de salida
DataOutputStream writer = new DataOutputStream(socket.getOutputStream());
reply(reader,writer);
// Cerramos los flujos
} catch (SocketTimeoutException e) {
System.err.println("300 segs sin recibir nada");
} catch (IOException e) {
System.err.println("Error: " + e.getMessage());
} finally {
try {
// Cerramos el socket
this.socket.close();
} catch (IOException ex) {
Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
public void reply(BufferedReader input, DataOutputStream output){
// Recibimos el mensaje del cliente
String requestLine = null;
try {
requestLine = input.readLine();
} catch (IOException ex) {
Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
}
String[] splittedHead = requestLine.split(" ",3);
String reqMethod = splittedHead[0];
String reqResource = "./" + checkFileRequested(splittedHead[1]);
String reqProtocol = splittedHead[2];
System.out.println(reqResource);
String resStateLine = reqProtocol;
String statusCode;
int fileType=0;
if("GET".equals(reqMethod) || "get".equals(reqMethod) || "HEAD".equals(reqMethod) || "head".equals(reqMethod)){
statusCode = "200 OK";
System.out.println(resStateLine);
}else{
statusCode = "400 Not Implemented";
try {
output.writeBytes(createHead(reqProtocol,statusCode,-1,0));
} catch (IOException ex) {
Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
}
}
File f = new File(reqResource);
if(!f.exists() || f.isDirectory()){
statusCode = "404 Not Found";
try {
output.writeBytes(createHead(reqProtocol,statusCode,-1,0));
} catch (IOException ex) {
Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
}
}else{
FileInputStream file = null;
try {
file = new FileInputStream(reqResource);
} catch (FileNotFoundException ex) {
Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
}
if(reqResource.toLowerCase().endsWith(".html")){
fileType = 1;
}
if(reqResource.toLowerCase().endsWith(".txt")){
fileType = 2;
}
if(reqResource.toLowerCase().endsWith(".gif")){
fileType = 3;
}
if(reqResource.toLowerCase().endsWith(".png")){
fileType = 4;
}
try {
output.writeBytes(createHead(reqProtocol,statusCode,fileType,f.length()));
} catch (IOException ex) {
Logger.getLogger(ThreadServer.class.getName()).log(Level.SEVERE, null, ex);
}
if("GET".equals(reqMethod)){
try{
while(true){
int b = file.read();
if(b == -1){
break;
}
output.write(b);
}
}catch(IOException e){
System.err.println(e);
System.err.println("No se pudo enviar el contenido de la respuesta correctamente");
}
}
}
}
public String checkFileRequested(String reqResource){
String[] resource = reqResource.split("/",2);
if(resource.length == 0){
return reqResource;
}else{
return resource[1];
}
}
public String createHead(String protocol,String statusCode,int fileType, long fileSize){
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss z").withZone(ZoneId.systemDefault());
LocalDateTime now = LocalDateTime.now();
String currentTime = "Date: " + now.format(dtf);
String serverMessage = "Server: Node.js/v10.15.0 (Raspbian)";
String contentLength = "Content-Length: " + fileSize;
String contentType = null;
switch(fileType){
default:
case -1:
contentType = "Content-Type: application/octet-stream";
break;
case 1:
contentType = "Content-Type: text/html";
break;
case 2:
contentType = "Content-Type: text/plain";
break;
case 3:
contentType = "Content-Type: image/gif";
break;
case 4:
contentType = "Content-Type: image/png";
break;
}
String head = protocol + " " + statusCode + System.lineSeparator() +
currentTime + System.lineSeparator() +
serverMessage + System.lineSeparator() +
contentLength + System.lineSeparator() +
contentType + System.lineSeparator();
return head;
}
}
我要测试的是使用netcat,先在端口2100上运行服务器,然后在 nc localhost 上运行,然后仅使用 get localhost / fic.png http / 1.1
我从netcat收到的答案如下:
get localhost/fic.png http/1.0
http/1.0 200 OK
Date: jue, 7 mar 2019 18:44:57 CET
Server: Node.js/v10.15.0 (Raspbian)
Content-Length: 13320
Content-Type: image/png
一切正常,如果文件不存在,它将给出404,如果它是未定义的方法,它将返回400。但是正如我之前在浏览器中所说,我看不到文档(仅适用于txt,这太奇怪了,因为我不认为MIME有任何问题。希望所有必要的信息都在帖子中。
非常感谢您:D
答案 0 :(得分:0)
解决了,如评论中所述,我对HTTP协议有误解。当我不得不离开2个行间距符时,我在内容和HEAD之间留下了1个行分隔符。