2014-12-10 2 views
0

Это упрощенное соединение сервер-клиент в Java, которое, похоже, не работает. Я сделал сервер, который правильно работает в браузере. Я также сделал http-соединение, которое получает данные с интернет-сайта. Тем не менее, заставить обоих поговорить друг с другом, кажется, сложно.Невозможно установить соединение между HttpURLConnection и HttpServer

У меня есть три класса. Common содержит строки и данные для классов Server и Client для использования.

Common.java:

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"; 
} 

Server.java:

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(); 
     } 
    } 
} 

Client.java

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(); 
     }  
    } 
} 

EDIT Я использовал сс -nt, чтобы определить, что соединение в какой-то мере происходит, хотя данные не bei перенесено.


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 
+0

Следует отметить, что в этом примере кода в обработчике не было exchange.close(). Я добавил это, но мой код проекта имеет метод close(), поэтому он не был частью моей исходной проблемы. – AaronF

ответ

0

I've изменил следующие пункты, и она работает в ноутбуке с Windows Vista и JDK 1.6.0_10:

Commons:

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

сервера, в методе ручки, написание некоторых символов для вывода и закрытия обмена:

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(); 
     } 

В классе Client я прочитал 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(); 
    } 
} 
+0

Изменение строки URL url = новый URL (Common.PROTOCOL, Common.HOST, Common.PORT, Common.PAGE); URL Url = новый URL ("http: // localhost: 39640"); работает по какой-то причине. Но я хочу, чтобы отдельные значения были переданы в качестве параметров в конечном результате, поэтому ... – AaronF

+0

Нет, изменение его обратно по-прежнему работает. Линией, с которой он работал, является IOUtils.toString (connection.getInputStream()); Думаю, это потому, что действие запроса от входного потока заставляет сервер обрабатывать запрос? – AaronF

+0

@AaronF В клиенте, если вы закрываете InputStream: connection.getInputStream(). Close(); он также работает. – rafalopez79

0

Ничего не происходит, если вы не получите входной поток, поток ошибок или код ответа.

Это потому, что выход буферизуется до тех пор, пока вы не сделаете так, чтобы заголовок Content-length можно было точно установить.

Вы можете обходить это, используя режим передачи каналов или фиксированной длины.

Смежные вопросы