有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

HttpURLConnection和HttpServer之间未建立java连接

这里有一个在Java中过于简化的服务器-客户机连接,它似乎不起作用。我已经做了一个服务器,可以正常地为浏览器服务。我还建立了一个http连接,可以很好地从互联网站点接收数据。然而,让两人互相交谈似乎很困难

我有三节课。Common包含服务器和客户端类要使用的字符串和数据

普通的。爪哇:

import java.io.Serializable;

public class Common {

    public static class Data implements Serializable{

        private static final long serialVersionUID = 1L;

        public String value = null;

        public Data(String value) {
            this.value = value;
        }
    }

    public static final String PROTOCOL = "http";

    public static final String HOST = "localhost";

    public static final Integer PORT = 39640;

    public static final String PAGE = "/test";

    public static final String POST = "POST";
}

服务器。爪哇:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;

import com.sun.net.httpserver.*;

@SuppressWarnings("restriction")
public class Server {

    public static class Handler implements HttpHandler {

        @Override
        public void handle(HttpExchange exchange) throws IOException {
            exchange.getResponseHeaders().add("accept", "*/*");
            try {
                ObjectInputStream in = new ObjectInputStream(exchange.getRequestBody());
                Common.Data data = (Common.Data) in.readObject();
                System.out.println(data.value);
                exchange.sendResponseHeaders(200, 0);
                exchange.close();
            } catch(Exception e) {
                exchange.sendResponseHeaders(404, 0);
                exchange.close();
            }           
        }

    }

    public static void main(String[] args) {

        InetSocketAddress socketAddress = null;
        HttpServer server = null;
        try {
            InetAddress address = InetAddress.getByName(Common.HOST);
            socketAddress = new InetSocketAddress(address, Common.PORT);
            server  = HttpServer.create(socketAddress, 10);

            //Add contexts
            server.createContext(Common.PAGE, new Handler());

            server.start();

        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

客户。爪哇

import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.URL;


public class Client {

    public static void main(String[] args) {
        try {
            URL url = new URL(Common.PROTOCOL, Common.HOST, Common.PORT, Common.PAGE);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();

            connection.setRequestMethod(Common.POST);
            connection.setDoOutput(true);
            connection.connect();

            ObjectOutputStream out = new ObjectOutputStream(connection.getOutputStream());
            out.writeObject(new Common.Data("Hello world"));

        } catch(Exception e) {
            e.printStackTrace();
        }       
    }
}

编辑 我使用ss-nt来确定连接是否以某种方式发生,即使没有数据传输


State      Recv-Q Send-Q                      Local Address:Port                        Peer Address:Port 
ESTAB      0      0                               10.0.2.15:46759                      108.168.151.6:80    
ESTAB      0      0                               10.0.2.15:59918                    198.252.206.149:443   
ESTAB      0      0                               127.0.0.1:39030                          127.0.0.1:52906 
ESTAB      0      0                        ::ffff:127.0.0.1:39640                   ::ffff:127.0.0.1:35764
ESTAB      0      0                        ::ffff:127.0.0.1:35764                   ::ffff:127.0.0.1:39640
ESTAB      0      0                        ::ffff:127.0.0.1:52906                   ::ffff:127.0.0.1:39030

共 (2) 个答案

  1. # 1 楼答案

    我改变了以下几点,它在一台装有Windows Vista和JDK 1.6.0_10的笔记本电脑上运行:

    公地:

    public static final String HOST = "127.0.0.1";
    //I´ve changed it to the localhost ip (windows)
    

    服务器,在handle方法中,将一些字符写入输出并关闭exchange:

     public void handle(final HttpExchange exchange) throws IOException {
            exchange.getResponseHeaders().add("accept", "*/*");
            try {
                final ObjectInputStream in = new ObjectInputStream(exchange.getRequestBody());
                final Common.Data data = (Common.Data) in.readObject();
                System.out.println(data.value);
                exchange.sendResponseHeaders(200, 0);
                exchange.getResponseBody().write("Hello!".getBytes());
    
            } catch (final Exception e) {
                exchange.sendResponseHeaders(404, 0);
            } finally {
                exchange.close();
            }
    

    在客户端类中,我从响应中读取InputStream并将其打印:

      public static void main(final String[] args) {
        try {
            final URL url = new URL(Common.PROTOCOL, Common.HOST, Common.PORT, Common.PAGE);
            final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
    
            connection.setRequestMethod(Common.POST);
            connection.setDoOutput(true);
            connection.connect();
    
            final ObjectOutputStream out = new ObjectOutputStream(connection.getOutputStream());
            out.writeObject(new Common.Data("Hello world"));
            out.close();
            final BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
    
            connection.disconnect();
        } catch (final Exception e) {
            e.printStackTrace();
        }
    }
    
  2. # 2 楼答案

    除非获得输入流、错误流或响应代码,否则不会发生任何事情

    这是因为在执行此操作之前,输出会被缓冲,因此可以准确设置内容长度标题

    您可以通过使用分块或固定长度传输模式来绕过这一点