使用套接字向服务器发送消息的错误请求 Java

Bad request sending message to server with Sockets Java

我正在尝试打开套接字、发送消息(请求 HEAD)并从服务器获取响应。

我的代码与我正在寻找的许多其他代码相似,在 SO 中,或谷歌搜索。

这里是:

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;

public class ClientTCPSocket {

    public static final int PORT = 80;

    public static void main(String argv[]) {


        BufferedReader inputKeyboard = new BufferedReader(new InputStreamReader(System.in));

        Socket socket;

        InetAddress ipAddress;

        String host = "";

        String head = "";

        String input_message = "";

        try {

            System.out.println("Host to connect?");

            host = inputKeyboard.readLine();
            head = "HEAD / HTTP/1.1\r\n"
                    + "Host: "+ host +"\r\n"
                    + "\r";
            ipAddress = InetAddress.getByName(host);

            socket = new Socket(ipAddress, PORT);

            DataOutputStream ouput = new DataOutputStream(socket.getOutputStream());


            System.out.println("\nSending info...");
            System.out.println(head);
            System.out.println("===============================");

            ouput.writeUTF(head);
            BufferedReader inputFromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));


            while ((input_message = inputFromServer.readLine()) != null) {
                System.out.println(input_message);
            }
            System.out.println("===============================");

            socket.close();
            inputFromServer.close();

        } catch (IOException e) {
            System.out.println("Alguna cosa ha anat malament");
            e.printStackTrace();
        }
    }
}

(正如我在 wiki 中读到的:https://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Message_format 我需要放置回车符和换行符。我这么说是因为我只使用“\n”进行测试)

但毕竟,如果我调用 "localhost"(我在 mac 中打开了一个基本的 xampp)甚至 "google.com",我会得到Error 400, BAD Request,我应该什么时候收到代码 200。

我不知道我忘记了什么或我必须发送哪些信息组合。

您的问题是由多种原因造成的:

writeUTF

的用法

来自 ouput.writeUTF(head);

的文档

Writes a string to the underlying output stream using modified UTF-8 encoding in a machine-independent manner. First, two bytes are written to the output stream as if by the writeShort method giving the number of bytes to follow. This value is the number of bytes actually written out, not the length of the string. Following the length, each character of the string is output, in sequence, using the modified UTF-8 encoding for the character. If no exception is thrown, the counter written is incremented by the total number of bytes written to the output stream. This will be at least two plus the length of str, and at most two plus thrice the length of str.

由于这 2 个字节是您的字符串的前缀,因此导致无效的 HTTP 请求

您应该手动将字符串转换为字节,然后发送,或者使用 InputStreamWriter

ouput.write(head.getBytes(StandardCharsets.UTF_8));

缺少尾随 \n

您在邮件中的最后一个换行符不完整

        head = "HEAD / HTTP/1.1\r\n"
                + "Host: "+ host +"\r\n"
                + "\r";

应该是

        head = "HEAD / HTTP/1.1\r\n"
                + "Host: "+ host +"\r\n"
                + "\r\n";

假设到达流的末尾

在 HTTP 1.1 中,默认情况下所有连接都是持久的,这意味着服务器会在请求后保持连接打开一段时间。

虽然您目前看不到效果(因为格式错误的请求,服务器假定其 HTTP 1.0),但如果您开始发送有效请求,这就是一个问题。

因为这意味着您的程序永远不会跳出 for 循环,我们需要检测请求的结束(很难!),或者降低效率并告诉服务器我们要关闭我们的连接:

        head = "HEAD / HTTP/1.1\r\n"
                + "Host: "+ host +"\r\n"
                + "Connection: close\r\n"
                + "\r\n";

缺少用户代理

虽然这并不违反协议,但某些服务器 可能 最近需要用户代理 header,并拒绝所有没有此 header.

这真的很简单。

        head = "HEAD / HTTP/1.1\r\n"
                + "Host: "+ host +"\r\n"
                + "user-agent: Test program made by https://whosebug.com/users/1282166/shudy\r\n"
                + "\r\n";