2014-09-23 2 views
1

Я пытаюсь создать однопоточный эхо-сервер, но я не могу понять, как снова отправить запрос от клиента обратно клиенту из сервер. Клиент подключается к серверу в порядке, но когда он ждет ответа, он генерирует исключение IOException. Я попытался подключить свой чат-клиент к другим чат-серверам, поэтому я уверен, что ошибка в реализации сервера чата.Создание эхо-сервера: подключенный клиент получает исключение IO

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

private void processClientRequest(Socket clientSocket) throws IOException { 
    InputStream in = clientSocket.getInputStream(); 
    PrintWriter out = 
     new PrintWriter(clientSocket.getOutputStream()); 
    long time = System.currentTimeMillis(); 

    out.write("Server - " + time + ": " + in); 

    out.close(); 
    in.close(); 
} 

Скажите, пожалуйста, если этот метод не является проблемой, и вам нужны другие части моего кода. Спасибо заранее!

Редактировать: Мне теперь удалось заставить мой сервер отвечать клиенту. Я сделал это, изменив метод processClientRequest к этому:

try { 
    BufferedReader in = 
     new BufferedReader(
      new InputStreamReader(clientSocket.getInputStream())); 

    PrintWriter out = 
     new PrintWriter(clientSocket.getOutputStream()); 

    long time = System.currentTimeMillis(); 

    out.write("Server - " + time + ": " + in.readLine()); 

    out.close(); 

    try { 
     in.close(); 
    } catch (IOException e) { 
     System.err.println("Couldn't close input stream"); 
    } 
} catch(IOException e) { 
     System.err.println("Got an IOException error while reading or writing from/to client"); 
} 

Но сейчас мой сервер может отвечать только клиент один раз. Если клиент записывает на сервер второй раз, он получает ответ, но вместо сообщения клиентов это «null». И так как я хочу, чтобы мой эхо-сервер мог отвечать клиенту до тех пор, пока клиент не выключится или что-то в этом роде, мне нужно выяснить, как это изменить. Я полагаю, что мне понадобится какой-то цикл while, чтобы это произошло, но я попытался, например, поставить весь оператор try в бесконечный цикл while, но это просто дало мне массу IOExceptions.

+0

Поскольку я совершенно новый для stackoverflow, мне нужно спросить: могу ли я задать следующий вопрос, как сейчас, с моим редактированием, или мне нужно создать совершенно новый поток? –

+0

Если ваш первый вопрос был дан ответ, отметьте принятый ответ соответствующим образом и спросите новый. Вы можете ссылаться на первый вопрос для справки. – Fildor

ответ

1

Вы не читаете входные данные клиентов. Вы просто передаете toString. Вам нужно сделать цикл while и прочитать из. Возможно, в отдельном потоке, если вы не уверены, что ввод короток. В тестовом коде должно быть в порядке:

private void processClientRequest(Socket clientSocket) throws IOException { 
     InputStream in = clientSocket.getInputStream();//wrap this in a object stream or other to read lines/ utf 
     int i = 0; 
     while(i++ < 1000 && in.available() > 0){ 
      int read = in.read();//use it if u want, like to a string builder declared out of loop and echo it back after u read input 
     } 
     PrintWriter out = 
     new PrintWriter(clientSocket.getOutputStream()); 
     long time = System.currentTimeMillis(); 

     out.write("Server - " + time + ": " + in); 

     out.close();//should be in seperate try catches so if 1 close fails u still close other and finally close socket in 3rd try catch 
     in.close(); 
} 

Socket server с работой эхо-сервера, мини-веб-сервер и полезным во многих других отношениях.

+0

Спасибо! Обертка моего InputStream в BufferedReader, поскольку предложенный комментарий помог мне понять, как я могу прочитать ввод от клиента. Я изменил строку InputStream на это: «BufferedReader in = new BufferedReader (новый InputStreamReader (clientSocket.getInputStream())); И строка out.write(): "out.write (" Сервер - "+ время +": "+ in.readLine());" Но, к сожалению, я не понимаю, как использовать цикл while, который вы предложили, и как он будет работать. На данный момент я могу отправить ответ клиенту, но только один раз. И я думаю, это то, что ваша петля должна решить. –

+0

Извините, мой комментарий слишком длинный, просто пришлось добавить, что я пробовал ваш цикл while, и я не мог заставить его работать. И даже если бы это сработало, я бы понятия не имел, почему. Зачем читать из InputStream, а затем помещать результат в Integer (почему Integer?), Который никогда не используется? Поэтому, если бы вы могли объяснить, как работает предложенный цикл while или как я должен что-то сделать с моим «новым решением», я был бы очень благодарен! :) –

+0

@JonatanStenbacka [InputStream # read()] (http://docs.oracle.com/javase/8/docs/api/java/io/InputStream.html#read--) возвращает 'следующий байт данных из входного потока, который является значением в диапазоне [0, 255] '. Чтобы внедрить эхо-сервер, вам нужно прочитать, какие клиенты отправляют на сервер, и отправлять его обратно им, т. Е. Записывать в OutpurStream клиентского сокета.Клиент нуждается в том, чтобы прочитать ответ сервера, который точно такой же, как и тот, который он отправил. – A4L