2013-12-12 3 views
0

Мне удалось настроить сервер, который будет принимать & управление несколькими клиентами сокета. , но теперь, когда я пытаюсь отправить сообщение, сервер просто ничего не получает, но я делаю сообщение.Многопользовательский сервер Java не получает сообщение от клиента?

Это метод, который управление клиентами: список

public void run() { 

    while(true) { 
     for (Client c : this.clients) { 
      try { 
       if (c.getStream().read() != -1) { 
        if (c.getInputStream() != null) { 
         System.out.println("He sent message"); 
         c.sendMessage("hey client"); 
        } 
       } 
      } catch (IOException e) { 
       c.destruct(); 
       this.clients.remove(c); break; 
      } 
     } 

     try { 
      Thread.sleep(100); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

Клиент:

public ArrayList<Client> clients = new ArrayList<Client>(); // client list 

И объект Клиент:

public class Client { 

    private Socket socket; 
    private int clientId; 
    private BufferedReader inStream; 
    private PrintWriter outStream; 
    private boolean socketAlive = true; 

    public Client(Socket sock) { 
     this.socket = sock; 
    } 

    public void setup() { 
     setInputOutputStream(); 
     System.out.println("New connection: " + this.getIpAddress()); 
     this.sendMessage("Successfully connected!"); 
    } 

    public BufferedReader getStream() { 
     return this.inStream; 
    } 

    public String getInputStream() { 
     String toReturn = ""; 
     try { 
      toReturn = this.inStream.readLine(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return toReturn; 
    } 

    public void destruct() { 
     try { 
      this.inStream.close(); 
      this.inStream = null; 
      this.outStream.close(); 
      this.outStream = null; 
      System.out.println("Client destruct: " + this.socket.getLocalSocketAddress()); 
      this.socket.close(); 
      this.socket = null; 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public Socket getConnection() { 
     return this.socket; 
    } 

    private void setInputOutputStream() { 
     try { 
      inStream = new BufferedReader(new InputStreamReader(this.socket.getInputStream())); 
      outStream = new PrintWriter(this.socket.getOutputStream()); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void sendMessage(String s) { 
     this.outStream.println(s); 
     this.outStream.flush(); 
    } 

    public String getIpAddress() { 
     return this.socket.getRemoteSocketAddress().toString(); 
    } 
} 

И на стороне клиента (отправитель):

public static void main(String[] args) { 
    try { 
     System.out.println("Client started"); 
     Socket sock = new Socket("localhost", 43594); 
     Scanner scanner = new Scanner(System.in); 
     String input; 
     PrintWriter out = new PrintWriter(sock.getOutputStream()); 
     BufferedReader reader = new BufferedReader(new InputStreamReader(sock.getInputStream())); 

     while (true) { 
      input = scanner.nextLine(); 

      if (input != null) { 
       out.print(input); 
       out.flush(); 
      } 
     } 
    } catch (IOException e) { 
     System.out.println("Client error"); 
    } 

} 

Почему мой сервер ничего не получает?

одно:

Если я отправить сообщение + отключиться, это то, что сервер будет регистрировать (Похоже, он только посылает сообщение на разъединение или что-то, ну нет, он входит в, если блок только на него) :

Server is successfully running on port 43594 
New connection: /127.0.0.1:57102 
He sent message 
java.net.SocketException: Connection reset 
    at java.net.SocketInputStream.read(Unknown Source) 
    at java.net.SocketInputStream.read(Unknown Source) 
    at sun.nio.cs.StreamDecoder.readBytes(Unknown Source) 
    at sun.nio.cs.StreamDecoder.implRead(Unknown Source) 
    at sun.nio.cs.StreamDecoder.read(Unknown Source) 
    at java.io.InputStreamReader.read(Unknown Source) 
    at java.io.BufferedReader.fill(Unknown Source) 
    at java.io.BufferedReader.readLine(Unknown Source) 
    at java.io.BufferedReader.readLine(Unknown Source) 
    at Client.getInputStream(Client.java:32) 
    at ClientHandler.run(ClientHandler.java:21) 
Client destruct: 0.0.0.0/0.0.0.0:43594 

Что я сделал не так? как я могу исправить это

сервера (основной класс)

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.*; 
import java.util.ArrayList; 

public class Server { 

    private int port = 43594; 

    public void listen() { 
     System.out.println("Trying to listen..."); 
     try { 
      final ServerSocket server = new ServerSocket(port); 
      // Create new thread to handle clients I/O 
      ClientHandler handler = new ClientHandler(server); 
      // START it 
      handler.start(); 
      System.out.println("Server is successfully running on port " + port); 
      while (true) { 
       // New connection found create a new Client object 
       Client cl = new Client(server.accept()); 
       cl.setup(); 
       // add it to clietns list in the I/O handler 
       handler.clients.add(cl); 
      }   
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

    } 

    public static void main(String[] args) { 
     // start up 
     System.out.println("Starting up.."); 

     // server instance 
     final Server server = new Server(); 

     // create a new thread for server 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       // listen for new connections 
       server.listen(); 
      } 
     }).start(); 
    } 
} 
+0

Почему у вас есть сервер для отправки сообщения клиенту? Чтобы настроить систему сервера сообщений, вы действительно хотите иметь что-то вроде многопоточных (так двух боковых потоков) сервера и клиента, а затем использовать обратные вызовы для обновления при получении сообщения. Я немного смущен вашей логикой. Являются ли ваши сервер и клиент двумя отдельными программами? и т. д. Пожалуйста, объясните немного больше, что ваша установка и проблема. –

+0

@ EthanBrouwer Да, это две разделенные программы, я добавил основной класс сервера, отредактированный. –

+0

Тем не менее 'c.sendMessage (« hey client »);'. Зачем ты это делаешь? 'c' является ссылкой на одного из ваших клиентов в arraylist, поэтому сервер не должен отправлять ему сообщение. Я думаю, что ваш клиент и ваш сервер испортились. –

ответ

0

Я думаю, что проблема исходит из того, что у вас есть список клиентов и пытаются управлять ими с этим. Я посмотрел java.net.SocketException: Connection reset, и нашел этот вопрос: What's causing my java.net.SocketException: Connection reset?

Ответ на этот вопрос приходит вверх с этим:

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

Это заставило меня думать, что вы не пользуетесь соединением с клиентом каждый раз. Вы храните его, а затем вы его теряете, поэтому сообщение не отправляется. Чтобы обращаться с большим количеством клиентов, скорее всего, вы захотите иметь список IP-адресов, а не клиентов, а затем подключиться, когда хотите отправить сообщение. Вы не можете сохранить соединение Socket. Он должен быть активным. Java (JVM) имеет свою собственную систему «Сбор мусора», которая просто убьет ее.

1

Клиент отправляет данные, и серверы читают.

Я думаю, что проблема в Client.getInputStream

this.inStream.readLine(), он читает строку текста. Из документации: «Читает строку текста». Линия считается завершенной любым каналом ('\ n'), возвратом каретки ('\ r') или возвратом каретки, за которым следует сразу перевод строки."

http://docs.oracle.com/javase/7/docs/api/java/io/BufferedReader.html

Если вы используете прочитать вместо этого, может быть, это будет работать. Просто используйте такой протокол, как отправка первые 1 или 2 байта с длиной сообщения. Или вы можете отправить«\ n 'от клиента.

Кстати, причина исключения на сервере при отправке и отключении на стороне клиента может быть связана с фактом TCP. Клиент закрыл соединение и, вероятно, получил TCP ACK от сервер. Затем TCP в клиенте отправляет сегмент RESET, но не уверен. Сервер был на этом.inStream.readLine(), а затем получил исключение. Разве вы также не получили сообщение «Соединение закрыто одноранговым узлом»?

1

Я не знаю, почему, но мне нужно было использовать out.println(input) out.flush() вместо .print() или .write()

У меня нет объяснения, почему мне нужно, чтобы сделать это. но это сработало.

+1

Это потому, что вы должны добавить \ n, как я объяснил вам в своем ответе – rodolk

+0

О, я вижу ... –

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