отправка запроса на сервер с помощью сокета в Java - PullRequest
1 голос
/ 26 января 2012

Я использую сокет для установления потокового соединения с сервером. Создав сокет, я попытался отправить запрос на сервер с помощью сокета. но запрос не получен сервером независимо от того, какой метод я использую. это методы, которые я использовал для отправки запроса.

PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
out.println(query);

или другой

 out = new ObjectOutputStream(connection.getOutputStream());
 out.writeObject(msg);
 out.flush();

запрос, который я пытаюсь отправить, выглядит примерно так:

String query = String.format("cmd=%s&version=%s", "handshake", "1.0");

Я знаю, что отправка этого запроса намного проще с использованием Httpconnection, но это способ, которым это нужно сделать. поэтому, пожалуйста, помогите мне с этим. это команды httpconnection

 String charset = "UTF-8";
 String query = String.format("cmd=%s&version=%s", "handshake", "1.0");
 String charset = "UTF-8";
 URL url = new URL("serveraddress:8080");           
 URLConnection conn = url.openConnection();         
 conn.setDoOutput(true);            
 conn.connect();            
 OutputStream output = conn.getOutputStream();              
 output.write(command.getBytes(charset));                                       

 InputStreamReader content = new InputStreamReader(conn.getInputStream());                              
 String result ="";
 int c = content.read();
 while (c != -1) {
    result = result + ((char) c);  
        c = content.read();
} 
 Log.v(logTag, "Received: [" + result + "]");

и это то, что я сделал в сокете, который не работал

 URL url = new URL("serveraddress:8080");               
 String server_name = url.getHost();
 int port = url.getPort();
 Socket socket = new Socket(server_name, port);                         

 String query = "post /swarm HTTP/1.1\nHost: serveraddress\n" +
 "content-length: 27\nkeep-alive: 300\nconnection: keep-alive\n\n" +
 "cmd=handshake&version=1.0\n"; 

 PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
 out.println(query);

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

1 Ответ

4 голосов
/ 26 января 2012

Три упомянутых вами метода (PrintWriter, ObjectOutputStream и HTTPConnection) приведут к тому, что что-то будет отправлено на сервер, но то, что на самом деле отправлено, будет сильно отличаться между различными методами.

Прежде всего, класс Java ObjectOutputStream будет кодировать объекты, которые вы в него пишете, вместе с информацией о классах, экземплярами которых являются эти объекты, особенно классимена, подписи и т. д. Это практически уместно только тогда, когда вы общаетесь с другим приложением Java, которое использует ObjectInputStream на другом конце для его чтения.В частности, он не будет придерживаться протокола HTTP, и, скорее всего, вы вообще не сможете использовать его с чем-либо, для чего вы можете использовать HTTPConnection.

Использование HttpURLConnection фактически создаст и отправит завершенные (и, самое главное, действительные) HTTP-запросы на сервер, к которому вы пытаетесь подключиться.Например, если вы должны выполнить следующий код:

URL url = new URL("http://localhost/test?cmd=handshake&version=1.0");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("GET");
connection.connect();

Тогда результатом будет ваше приложение, подключающееся к localhost: 80 и записывающее что-то вроде следующего: (Этоупрощенный запрос. В текущем запросе будут дополнительные заголовки и информация.)

GET /test?cmd=handshake&version=1.0 HTTP/1.1
Host: localhost

Наконец, если вы используете PrintWriter , то он фактически отправит чистый текст на сервер.Однако, если сервер является HTTP-сервером, что, вероятно, так как вы говорите, что он отвечает на HTTP-соединение, недостаточно просто отправить командную часть запроса.Вам также нужно будет отправить остальные, включая GET , версию HTTP, возможно, некоторые заголовки, завершающие пустые строки и окончания строк CRLF.Все это можно сделать с помощью PrintWriter.

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

Я также рекомендовал бы прочитать некоторые подробности, касающиеся протокола HTTP.Хорошей отправной точкой может стать статья в Википедии .

Редактирование на основе новой информации в OP:

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

Решение, основанное на URLConnection, нигде не указывает ресурс "/ swarm".Добавление этого не изменится, будет ли запрос фактически отправлен или нет, или даже если он действителен или нет, но это может повлиять на то, можете ли вы найти запрос в журналах или нет.

Строка запроса в целом выглядит разумной, за исключением того, что POST написано строчными буквами.Сначала я не думал, что это будет иметь какое-либо значение, но при попытке "получить" против "GET" против www.google.com через Telnet это, похоже, имеет значение.Если веб-сервер не распознает запрос как запрос, он не сможет его обработать и, следовательно, он может не отображаться в журналах, как вы ожидаете.

Я бы порекомендовал вам на самом деле прочитать ответ сервера и распечатать его в System.out, чтобы увидеть, сообщает ли сервер какую-либо конкретную ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...