使用 Java Socket 发送 HTTP 响应时遇到问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10638848/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 01:56:01  来源:igfitidea点击:

Trouble sending HTTP response with Java Socket

javahttpsockets

提问by webhound

I've been trying to write the beginnings of a simple web server, but can't seem to get the response to get sent. I've tried every type of Output stream imaginable but nothing seems to work. I'm at a loss. Here are the two classes I'm using, sorry about some of the extraneous code:

我一直在尝试编写一个简单的 Web 服务器的开头,但似乎无法获得要发送的响应。我已经尝试了所有可以想象的输出流类型,但似乎没有任何效果。我不知所措。这是我正在使用的两个类,对一些无关代码感到抱歉:

package edu.xsi.webserver;

import java.io.IOException;
import java.net.ServerSocket;


public class WebServer {

int port;
ServerSocket server;

public WebServer(int port) throws IOException{

    this.port = port;
    this.server = new ServerSocket(port);
    Thread t = new Thread(new ServerExec());
    t.start();

}

public class ServerExec implements Runnable {

    public void run(){

        int i = 0;
        while (true) {

            try {
                new WebSession(server.accept(), i++);
                System.out.println("Should print before session");
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }


}

public static void main(String[] args) {

    try {
        WebServer webServer = new WebServer(8888);
    } catch (IOException e) {
        e.printStackTrace();
    }
}
}

This is the session class that handles the response.

这是处理响应的会话类。

package edu.xsi.webserver;

import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;

public class WebSession implements Runnable {

Socket client;
int num;

public WebSession(Socket client, int num) {

    this.num = num;
    this.client = client;
    Thread t = new Thread(this);
    t.start();
}


public void run() {

    Scanner s = null;
    DataOutputStream out = null;

    try {

        s = new Scanner(client.getInputStream());
        out = new DataOutputStream(client.getOutputStream());

        //Get all input from header
        while (s.hasNextLine()) {
            System.out.println(s.nextLine());
        }
        out.writeBytes("HTTP/1.1 200 OK\r\n");
        out.writeBytes("Content-Type: text/html\r\n\r\n");
        out.writeBytes("<html><head></head><body><h1>Hello</h1></body></html>");

        s.close();
        out.flush();
        out.close();

    } catch(IOException ioe) {

        ioe.printStackTrace();
    }

}

}

}

回答by Mena

I've been struggling like crazy with a very similar issue.

我一直在为一个非常相似的问题疯狂地挣扎。

After literally head-banding on the wall I found myissue was so trivial I kept on head-banging on the wall for a while.

在墙上真正地用头箍后,我发现我的问题是如此微不足道,我一直在墙上头撞了一会儿。

Basically in my input while loop I was checking for a null line, but I forgot to check for an empty line(and subsequently break).

基本上在我的输入 while 循环中,我正在检查空行,但我忘记检查空行(随后中断)。

No guarantee it'll work the same for you but here's my one cent:

不能保证它对你有用,但这是我的一分钱:

in = session.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
String line = null;
while ((line = br.readLine()) != null) {
    System.out.println(line);
    // this seems to be the key for me! 
    // somehow I never get out of this loop if I don't 
    // check for an empty line...
    if (line.isEmpty()) {
        break;
    }
}
out = new BufferedWriter(
    new OutputStreamWriter(
        new BufferedOutputStream(session.getOutputStream()), "UTF-8")
);
out.write(OUTPUT_HEADERS + OUTPUT.length() + OUTPUT_END_OF_HEADERS + OUTPUT);
out.flush();
out.close();
session.close();

My constants are:

我的常数是:

private static final String OUTPUT = "<html><head><title>Example</title></head><body><p>Worked!!!</p></body></html>";
private static final String OUTPUT_HEADERS = "HTTP/1.1 200 OK\r\n" +
    "Content-Type: text/html\r\n" + 
    "Content-Length: ";
private static final String OUTPUT_END_OF_HEADERS = "\r\n\r\n";

My "session" variable is a Socketobject.

我的“会话”变量是一个Socket对象。

回答by user207421

Closing the Scanner closes the underlying input stream, which closes the socket. Don't close it. Closing the output stream also closes the socket. You don't need both, and you should close the output stream/writer rather than the input stream so it gets flushed.

关闭扫描器将关闭底层输入流,从而关闭套接字。不要关闭它。关闭输出流也会关闭套接字。您不需要两者,您应该关闭输出流/编写器而不是输入流,以便它被刷新。

回答by Sajal Goyal

The below code will solve your problem:

下面的代码将解决您的问题:

package com.cs.sajal;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class TestCls {

    public static void main(String[] args) {
        boolean flag = false;

        try {
            ServerSocket ss = new ServerSocket(8080);
            if (ss.isBound()) {
                while (flag = true) {
                    final Socket s = ss.accept();



                    Thread t1=new Thread(new Runnable (){String line = null;public void run(){try{ InputStream is = s.getInputStream();
                    BufferedReader br = new BufferedReader(
                            new InputStreamReader(is));

                    while ((line = br.readLine()) != null) {
                        System.out.println(line);
                    }
                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                    }});

                    Thread t2=new Thread(new Runnable (){String line = null;public void run(){try{ OutputStream os = s.getOutputStream();
                    Scanner sc=new Scanner(System.in);
                    String inp=null;
                    String t="HTTP/1.1 200 OK\r\n";
                    byte[]s=t.getBytes("UTF-8");
                    os.write(s);

                    t="Content-Length: 788\r\n";
                    s=t.getBytes("UTF-8");
                    os.write(s);
                    t="Content-Type: text/html\r\n\r\n";
                    s=t.getBytes("UTF-8");
                    os.write(s);


                    t="\r\n\r\n<html><body><h1>this is output</h1><table cellpading=5 border=5><tr><td>name</td><td>age></td><td>height</td></tr></table></body></html>\r\n\r\n";
                    s=t.getBytes("UTF-8");
                    os.write(s);
                    t="Connection: Closed";
                    s=t.getBytes("UTF-8");
                    os.write(s);

                    os.flush();
                    }
                    catch(Exception e)
                    {
                        e.printStackTrace();
                    }
                    }});
                    t1.start();
                    t2.start();t1.join();
                    t2.join();


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

回答by cassio.moreto

Try pass the date.

尝试通过日期。

 String res = "HTTP/1.0 200 OK\n"
?????????+ "Server: HTTP server/0.1\n";
?????????+ "Date: "+format.format(new java.util.Date())+"\n";?
???+ "Content-type: text/html; charset=UTF-8\n";?
?????????+ "Content-Length: 38\n\n";
?????????+ "<html><body>OK</body></html>";
out.write(res.getBytes());
out.flush();

private SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:Ss z");