对Java中的http请求使用writeUTF和readUTF

时间:2018-04-17 05:07:48

标签: java sockets networking

这是一种尝试抓取指定网页的Java方法。我使用writeUTF和readUTF进行与服务器的套接字通信。

static void get_html(String host, String page, int port) throws IOException {
        Socket sock = new Socket(host, port);
        String msg = MessageFormat.format("GET {0} HTTP/1.1\r\nHost: {1}\r\n\r\n", page, host);

        DataOutputStream outToServer = new DataOutputStream(sock.getOutputStream());
        DataInputStream inFromServer = new DataInputStream(sock.getInputStream());

        InputStream stream = new ByteArrayInputStream(msg.getBytes(StandardCharsets.UTF_8));
        BufferedReader buf = new BufferedReader(new InputStreamReader(stream));
        String outMsg;

        while ((outMsg = buf.readLine()) != null) {
            System.out.println("Sending message: " + outMsg);
            outToServer.writeUTF(outMsg);

            String inMsg;
            try {
                inMsg = inFromServer.readUTF();
            } catch (EOFException eof) {
                break;
            }
            System.out.println(inMsg);
        }
        sock.close();
    }

我这样编写的原因是模仿c代码,其中有一个send()的while循环从缓冲区进行所有传递,另一个循环为{{1}从缓冲区直到它命中'null'。当执行我的代码时,它只是挂起,我怀疑这是由于在我发送完所有消息之前调用了readUTF。如果是这种情况,有没有办法解决它?

1 个答案:

答案 0 :(得分:0)

你不能这样做。 HTTP定义为文本行。 writeUTF()不写文本,它写一个以16位二进制长度字开头的特殊格式。同样,HTTP服务器也不会使用该格式回复您的readUTF()电话。见Javadoc。

您必须使用二进制流和write()方法,并使用\r\n作为行终止符。根据输出格式,您可能会或可能无法使用readLine()。最好不要,那么你不必编写两段代码:再次使用二进制流。

实际上你应该扔掉它并使用HttpURLConnection。实现HTTP并不像匆忙那样简单。