2015-12-18 3 views
0

Предполагалось, что это будет 5-минутный тест, чтобы увидеть, работает ли он так, как было предложено. Я хотел создать глупо простой HTTP-сервер, который ничего не делает, кроме как распечатывать то, что получает (а именно HTTP-запросы).Сокет Java: Чтение не возвращается

public static void main(String args[]) throws IOException { 
    ServerSocket server = new ServerSocket(port); 
    try (Socket socket = server.accept()) { 
     DataInputStream input = new DataInputStream(socket.getInputStream()); 
     String received = input.readUTF(); 
     System.out.println("Received: \n" + received); 
    } 
} 

Но я пришел со следующей проблемой: Когда я начинаю свою программу, а затем попробовать http://localhost/ в Firefox, поток застревает в методе readUTF(). Он просто не возвращается.

Я пробовал то же самое с сокетными каналами и размером буфера 128. Там он застревает после третьего чтения (так где-то между 384 и 511-м байтами). Это следующий код:

public static void main(String args[]) throws IOException { 
    CharsetDecoder decoder = Charset.forName("UTF8").newDecoder(); 
     ServerSocketChannel serverSocketChannel = ServerSocketChannel.open(); 
     serverSocketChannel.bind(new InetSocketAddress(port)); 
     ByteBuffer buffer = ByteBuffer.allocate(bufferSize); 
     buffer.clear(); 
     SocketChannel socketChannel = serverSocketChannel.accept(); 
     StringBuilder received = new StringBuilder(); 
     while (socketChannel.read(buffer) > 0) { 
      buffer.position(0); 
      received.append(decoder.decode(buffer).toString()); 
      buffer.clear(); 
     } 
     System.out.println("Received: \n" + received.toString()); 
    } 

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

+0

Я не видел код, который записывает данные в Socket. Можете ли вы опубликовать эту часть кода? –

+0

Это делается браузером. Как я уже упоминал выше, этот код прослушивает порт 80 (HTTP-сервер), и поэтому он подключается к браузеру, когда я запрашиваю 'http: // localhost'. Соединение работает нормально, и во втором примере я могу читать 384 байта (цикл 3x) до тех пор, пока чтение не застрянет. Но HTTP GET-сообщение длиннее 384 байт. Похоже, что в четвертом цикле он не признает, что данные уже закончены, и он ждет больше. Но, тем не менее, он должен возвращать и сохранять оставшиеся данные в буфер. – Green

ответ

0

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

Этот поток не используется для ваших нужд, просто прочитайте его с getInputStream() или оберните его BufferedReader.

+0

Хорошо. Спасибо за предложение. Но, полагаю, использование 'BufferedReader' вместо' DataInputStream' не решит проблему, с которой я столкнулся, поскольку в версии, где я использовал каналы сокетов, у меня такая же проблема. Я также опубликую другое решение. – Green

+0

Вопрос в том, получает ли сервер какие-либо данные, т. Е. Посылает ли клиент что-либо. В противном случае, вы уверены, что во втором случае 'read()' не заканчивается или только цикл не заканчивается? Для цикла это очень вероятно, так как клиент не закрывает соединение, пока не получит ответ. Вы пытались запустить это в отладчике? –

+0

Конечно, я прошел через код, используя отладчик, и после 3 циклов он застрял в методе 'read'. Итак, я думал, что причина должна быть связана с чем-либо с помощью взаимодействия между браузером и сервером. Насколько я знаю, когда клиент что-то пишет в сокет, другой конец может прочитать его полностью, а затем он имеет возможность ответить. Но в этом случае я даже не получаю ответа, потому что он застревает. – Green

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