Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java TCP套接字HTTP获取请求内容长度>;0,但不返回实际内容_Java_Spring_Sockets_Http - Fatal编程技术网

Java TCP套接字HTTP获取请求内容长度>;0,但不返回实际内容

Java TCP套接字HTTP获取请求内容长度>;0,但不返回实际内容,java,spring,sockets,http,Java,Spring,Sockets,Http,我试图使用TCP套接字而不是HTTPClient查询托管在Tomcat/Spring启动应用程序上的REST API服务,因为我无法使用HTTPClient。我能够成功地打开套接字、发送请求并从服务器接收数据,但服务器响应中从未返回任何正文或内容。如果我使用web浏览器来查询相同的URL,它就可以正常工作。以下是我用于发出请求的程序: import java.io.BufferedReader; import java.io.InputStream; import java.io.InputSt

我试图使用TCP套接字而不是HTTPClient查询托管在Tomcat/Spring启动应用程序上的REST API服务,因为我无法使用HTTPClient。我能够成功地打开套接字、发送请求并从服务器接收数据,但服务器响应中从未返回任何正文或内容。如果我使用web浏览器来查询相同的URL,它就可以正常工作。以下是我用于发出请求的程序:

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.Socket;

public class SocketClient {

    public SocketClient() {
        String hostname = "192.168.10.104";
        int port = 8080;

        try (Socket socket = new Socket(hostname, port)) {

            OutputStream output = socket.getOutputStream();
            PrintWriter writer = new PrintWriter(output, false);

            writer.println("GET /company/1 HTTP/1.1");
            writer.println("Host: " + hostname + ":" + port);
            writer.println("User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36");
            writer.println("Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8");
            writer.println("Accept-Language: en-US,en;q=0.9");
            writer.println("Accept-Encoding: gzip, deflate, br");
            writer.println("Connection: close");
            writer.println();
            writer.flush();

            InputStream input = socket.getInputStream();

            BufferedReader reader = new BufferedReader(new InputStreamReader(input));

            String line;

            while (!(line = reader.readLine()).equals("")) {
                System.out.println(line);
            }
            socket.close();
        } catch (Exception ex) {

            System.out.println("Server not found: " + ex.getMessage());

        }

    }
}
服务器使用以下数据进行响应:

HTTP/1.1 200 
Content-Type: text/html;charset=UTF-8
Content-Length: 55
Date: Thu, 24 Jan 2019 15:45:00 GMT
Connection: close

响应表明应该有一些基于内容长度的内容,但我从未实际收到内容本身。有可能这样做吗?非常感谢您的建议。

当您发现空行时,请停止阅读。有一个空行将标题和内容分开,所以您只是不阅读内容

当服务器关闭连接时,readLine返回null。将循环更改为

while (!(line = reader.readLine()) == null)

当你发现一个空行时,你就停止阅读。有一个空行将标题和内容分开,所以您只是不阅读内容

当服务器关闭连接时,readLine返回null。将循环更改为

while (!(line = reader.readLine()) == null)

谢谢Joni,我改变了循环,它确实工作了,但现在的情况是它打印我发布的原始数据,然后在大约30秒后(我认为这是某种超时),它最终获取并打印内容。查看Wireshark,当它从服务器接收到最终确认时,它会打印内容。您知道是否有任何方法可以加快这一速度吗?您可以尝试告诉服务器,您不会使用
socket.shutdownOutput()
,发送更多请求-这可能会说服tomcat在发送响应后关闭连接。或者您可以实现更多HTTP规范:解析内容长度头,并在读取了正文的那么多字节后停止读取。如果内容恰好是ASCII,则将读取55个字节:
char[]content=new char[55];for(inti=0;i<55;i+=reader.read(content,i,55-i))
如果您使用非ASCII字符,则很难读取准确的字节数,这就是http客户端库存在的原因。从响应头可以看到,返回的内容以UTF-8编码。但是您使用的是InputStreamReader,默认情况下,它将使用客户端的默认字符集进行解码。因此,如果服务器发送任何非纯ASCII的内容,并且您的默认字符集不是UTF-8,那么您将遇到麻烦。正如上面乔尼暗示的,这些事情并不是完全微不足道的。如果服务器使用任何与ASCII不兼容的编码,那么您必须首先使用ASCII读取标题,然后使用服务器指定的任何字符集读取内容。感谢Joni,我更改了循环,它确实有效,但现在的情况是,它打印了我发布的原始数据,然后大约30秒后(我认为这是某种超时)它最终获取并打印内容。查看Wireshark,当它从服务器接收到最终确认时,它会打印内容。你知道是否有任何方法可以加快这一速度吗?你可以尝试告诉服务器,你不会使用
socket.shutdownOutput()发送更多请求
-这可能会说服tomcat在发送响应后关闭连接。或者您可以实现更多的HTTP规范:解析内容长度头,并在读取了正文的那么多字节后停止读取。如果内容恰好是ASCII,则将读取55个字节:
char[]content=new char[55];例如(inti=0;i<55;i+=reader.read(content,i,55-i))
如果您使用非ASCII字符,则很难读取准确的字节数,这就是为什么http客户端库存在于响应头中,您可以看到返回的内容以UTF-8编码。但是您使用的是InputStreamReader,默认情况下,它将使用客户端的默认字符集进行解码。因此,如果服务器如果您不使用任何非纯ASCII的编码,并且您的默认字符集不是UTF-8,那么您将遇到麻烦。正如上面Joni所暗示的,这些事情并不完全是无关紧要的。如果服务器使用任何与ASCII不兼容的编码,那么您必须首先使用ASCII读取标题,然后使用服务器指定的任何字符集读取内容。