1

私はHTTPサーバーでいくつかのベンチマークを行っています。HTTPライブラリとの潜在的な競合を回避するために、HTTP持続的接続を使用せずに、Socketを使用して直接接続を開きます。

Javaコードが開きInputStream、ロードされたHTTPサーバーに接続されたソケットに接続します。Linux上で実行されています。

これらのいずれかが発生する可能性があることがわかります。

  • ソケット接続(new Socket())には時間がかかる場合があります。これは、サーバーに新しい接続の受け入れにバックログがある場合に意味があります。
  • ソケット接続は高速ですが、read()が-1を返し、ストリームが「ファイル」の最後にあることを示す場合、最大1500ミリ秒の遅延が最後の読み取りにあります。これはわかりません。

コードは標準に準拠していますが、いくつかのタイミングコードが追加されています。

final byte[] buffer = new byte[8192];
int size = inputStream.read(buffer);

while (size > 0) {
    // Copy the buffer
    size = inputStream.read(buffer);
}
4

3 に答える 3

5

readサーバーが送信しようとしているすべてのデータをすでに受信した後で、電話をかけています。これは間違いです。(HTTPプロトコルによって決定される)完全な応答を受信したら、の呼び出しを停止する必要がありますread。接続がタイムアウトするのを待っていますが、これはばかげています。

HTTPプロトコルは、TCPプロトコルではなく、完全な応答を受信したときに通知します。TCPスタックがHTTPを理解することを期待しています。そうではありません。完全な返信をいつ受け取ったかはわかりません。

于 2012-09-03T12:23:32.633 に答える
2

ソケット接続は高速ですが、read()が-1を返し、ストリームが「ファイル」の最後にあることを示す場合、最大1500ミリ秒の遅延が最後の読み取りにあります。これはわかりません。

シナリオがあなたが説明した通りであると仮定します。つまり、ポート80に接続して、データを読み取ろうとしただけです。

  • サーバーは、クライアントコードがリクエストを送信するのを待っている可能性があります。
  • サーバーは1.5秒後に読み取りをタイムアウトし、ソケットの両側を閉じます。
  • その結果、クライアント側のソケットはEOF ...を認識します。これは、呼び出し-1から戻ることによってコードに通知されます。read(...)

基本的に、サーバーが応答を送信することを期待している場合、コードは整形式のHTTP要求をサーバーに送信する必要があります。

一方、コード整形式のHTTPリクエストを送信した場合、この動作は、サーバーが送信する必要のあるデータをさらに読み取ろうとするコードと、永続的な接続を指定したリクエストの送信が原因である可能性があります。 (HTTP 1.1仕様、セクション8.1を参照)。

于 2012-09-03T12:31:11.993 に答える
1

JSON本文で応答を受信したときに同様の問題が発生しました。いくつかの実験の後、私はそのプログラムが体を読んでいる間にぶら下がっているのを検出しました。そこで、ヘッダーからContent-Lengthを読み取り、空白行(ヘッダーと本文の間)の後で停止し、その後に必要な文字のみを読み取ることで、これを解決しました。コードは次のとおりです。

import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;

public class TelegramSocketClient {
    private final String CONTENT_LEN = "Content-Length:";
    Socket clientSocket;
    SSLSocket sslSocket;
    PrintWriter out;
    BufferedReader in;
    public void startSSLConnection(String ip, int port) throws IOException {
SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory
                .getDefault();
        sslSocket = (SSLSocket) factory.createSocket(ip, port);

        out = new PrintWriter(sslSocket.getOutputStream(), true);
        in = new BufferedReader(
                new InputStreamReader(sslSocket.getInputStream(), StandardCharsets.UTF_8));
    }

    public String sendMessage(String msg) throws IOException {
        out.println(msg);
        String line = null;
        int contentLen = 0;
        while ((line = in.readLine()) != null && !line.isEmpty()) {
            System.out.println(line);
            if(line.startsWith(CONTENT_LEN)) {
                contentLen = Integer.parseInt(line.substring(CONTENT_LEN.length() +1, line.length()));
            }
        }

        char [] buff = new char[contentLen];
        in.read(buff, 0, buff.length);
        return new String(buff, 0, buff.length);
    }

    public void stopConnection() throws IOException {
        in.close();
        out.close();
        clientSocket.close();
    }
}
于 2020-03-17T20:31:04.153 に答える