Программирование сокетов Java - поток застрял - PullRequest
0 голосов
/ 03 марта 2010

В настоящее время я работаю на простом прокси-сервере, который получает http-запрос от браузера, обрабатывает его и пересылает на веб-сервер желаний.

Я пытаюсь получить запрос из входного потока сокета, подключенного браузером, все хорошо, за исключением того, что поток застревает после получения последнего блока данных.

Мой код на самом деле очень прост, как показано ниже:

ServerSocket servSocket = new ServerSocket(8282);  
Socket workSocket = servSocket.accept();  
InputStream inStream = workSocket.getInputStream();  
byte[] buffer = new byte[1024];  
int numberRead = 0;  

while ((numberRead = inStream.read(buffer, 0, 1024)) != -1){  
System.out.println(new String(buffer));  
}  

Цикл просто не может выйти, даже прием запроса завершен.

Есть ли способ обойти эту проблему?

Заранее спасибо за любой совет.

Ответы [ 5 ]

1 голос
/ 03 марта 2010

Как и в InputStream javadoc , метод будет блокироваться до тех пор, пока не будут доступны данные или не будет обнаружен EOF. Итак, другая сторона Socket должна его закрыть - тогда вызовет inStream.read ().

Другой способ - отправить размер сообщения, которое вы хотите прочитать первым, чтобы вы знали заранее, сколько байтов вам нужно прочитать. Или вы можете использовать BufferedReader для чтения из сокета построчным способом. В BufferedReader есть метод readLine (), который возвращает каждый раз при чтении строки, который должен работать для вас, так как пакеты протокола HTTP хорошо разделены на строки.

0 голосов
/ 03 марта 2010

Когда приходит http-запрос, всегда завершается пустой строкой, например:

GET /someFile.html HTTP/1.1
Host: www.asdf.com

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

0 голосов
/ 03 марта 2010

Не является прямым решением в соответствии с вашим текущим кодом.

Поскольку HTTP является линейным протоколом, вы можете использовать Buffered Reader и вызывать readLine() для него.

0 голосов
/ 03 марта 2010

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

0 голосов
/ 03 марта 2010

Он будет работать до тех пор, пока соединение не будет закрыто, и клиент, вероятно, ожидает от вас ответа HTTP и не закрывает его.

...