2

クライアントからサーバーに向かう 2 つの HttpURLConnections があります。これは典型的な HttpServer ではありません。クライアントとサーバーの両方をコーディングしていますが、ポート 80/443 しか使用できません (ポートの動作をテストするため)。最初のリクエストは正常に処理されますが、2 番目のリクエスト (最初のリクエストの直後に発生) はサーバーに到達できません。HttpExchange.closeHttpURLConnection.disconnectを呼び出して、すべてのストリームをフラッシュしていますが、サーバーに到達するための 2 番目の要求を取得できません。私は Oracle の JDK 1.7_17 x64 を使用しており、Win7 x64 で実行しています。以下は、SSCCE の出力と SSCCE です。私は何が欠けていますか?

サーバ

Started server @ /127.0.0.1:8765
Handling HttpExchange!
Processing request from user: joe.smith

クライアント:

ClientID: 0
Response code: 200

SSCCE は次のとおりです。

import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.URL;
import javax.swing.JOptionPane;

public class CommsTest {

    public static void main(String[] args) throws IOException {
        Object startMe = JOptionPane.showInputDialog(null, "Start client or server?", "Launcher", JOptionPane.QUESTION_MESSAGE, null,
                new Object[]{"Client", "Server"}, "Server");
        if (startMe.equals("Server")) {
            HttpServer httpServer = HttpServer.create(new InetSocketAddress("localhost", 8765), 50000);
            httpServer.createContext("/test", new HttpHandler() {
                private byte clientIdCounter = 0;

                @Override
                public void handle(HttpExchange he) throws IOException {
                    System.out.println("Handling HttpExchange!");
                    int requestCode = Integer.parseInt(he.getRequestHeaders().getFirst("ReqCode"));
                    switch (requestCode) {
                        case 0:
                            // request '0' sends username and accepts a byte back
                            try (ObjectInputStream ois = new ObjectInputStream(he.getRequestBody())) {
                                System.out.println("Processing request from user: " + ois.readUTF());
                            }
                            // send a response of code of 200, all is well! and i'm sending 1 byte back.
                            he.sendResponseHeaders(200, 1);
                            he.getResponseBody().write(new byte[]{clientIdCounter++});
                            he.close();
                            break;
                        case 1:
                            // request '1' sends 3 bytes
                            try (ObjectInputStream ois = new ObjectInputStream(he.getRequestBody())) {
                                byte clientId = ois.readByte();
                                byte opCode = ois.readByte();
                                byte argument = ois.readByte();
                                System.out.println(String.format("Received op request %d from client %d with argument %d", clientId, opCode,
                                        argument));
                                // send a response code of 200, all is well! no data is being sent back though.
                                he.sendResponseHeaders(200, 0);
                                he.close();
                            }
                            break;
                    }
                }
            });
            httpServer.start();
            System.out.println("Started server @ "+ httpServer.getAddress());
        } else if (startMe.equals("Client")) {
            // first phase of the connection, send a opCode of 0, send the username, receive the client id
            HttpURLConnection con = create(true, true, 0);
            try (ObjectOutputStream oos = new ObjectOutputStream(con.getOutputStream())) {
                oos.writeUTF(System.getProperty("user.name"));
            }
            byte clientId = (byte) con.getInputStream().read();
            System.out.println("ClientID: " + clientId);
            System.out.println("Response code: "+ con.getResponseCode());
            con.disconnect();
            // next phase of connection, send an opCode of 1 and 3 bytes, receive nothing
            con = create(false, true, 0);
            try (ObjectOutputStream oos = new ObjectOutputStream(con.getOutputStream())) {
                oos.writeByte(0);
                oos.writeByte(4);
                oos.writeByte(2);
                oos.flush(); //I've also tried closing the oos manually and calling con.disconnect, to no avail
            }
        }
    }

    private static HttpURLConnection create(boolean input, boolean output, int reqCode) throws IOException {
        URL url = new URL("http://localhost:8765/test");
        HttpURLConnection con = (HttpURLConnection) url.openConnection();
        con.setUseCaches(false);
        //I have tried #setRequestMethod("POST") but that didn't help
        con.setDoInput(input);
        con.setDoOutput(output);
        con.setRequestProperty("ReqCode", Integer.toString(reqCode));
        return con;
    }
}
4

1 に答える 1