2015-02-12 8 views
1

Хорошо, поэтому я закодировал, что будет простой коммуникационной программой, использующей сервер, действительно как тест больше, чем что-либо еще, поэтому я знаю, что это не так много , но со следующим классом Client:Объявление потоков ввода/вывода из программы предотвращения сокета от продолжения

public class Client { 
    private ObjectInputStream in; 
    private ObjectOutputStream out; 

    private Socket socket; 

    private String server; 
    private int port; 

    public Client(String ip, int p){ 
     port = p; 
     server = ip; 
    } 

    public boolean start(){ 
     try{ 
      socket = new Socket(server, port); 
     }catch(Exception e){ 
      System.out.println("Exception"); 
      e.printStackTrace(); 
      return false; 
     } 
     try{ 
      in = new ObjectInputStream(socket.getInputStream()); 
      out = new ObjectOutputStream(socket.getOutputStream()); 
      System.out.println("All declared"); 
     }catch(Exception e){ 
      System.out.println("Exception"); 
      e.printStackTrace(); 
      return false;} 
     new LThread().start(); 
     return true; 
    } 

    private void sendMessage(Message msg){ 
     try{ 
     out.writeObject(msg); 
     }catch(Exception e){} 
    } 

    public static void main(String[] args){ 
     int portNum = 1500; 
     String servers = "localhost"; 

     Client client = new Client(servers, portNum); 

     System.out.println("Client started"); 

     if(!client.start()){ 
      System.out.println("Didn't work"); 
      return; 
     } 

     System.out.println("Client started again"); 


     Scanner scan = new Scanner(System.in); 

     while(true){ 
      String i = scan.nextLine(); 
      client.sendMessage(new Message(2, i)); 
     } 
    } 

    class LThread extends Thread{ 

     public void run(){ 
      System.out.println("Lthread running"); 
      while(true){ 
       try{ 
        String message = (String)in.readObject(); 
        System.out.println(message); 
       }catch(Exception e){ 
        e.printStackTrace();} 
      } 
     } 

    } 
} 

программа просто останавливается, когда он достигает точки, в которой он заявляет о своей ObjectInput и OutputStream с. Программа не выходит, она, похоже, не вводит блок catch, и я вообще не могу понять, что может быть причиной этого. Строка «Все объявлено». никогда не печатается, а что-либо перед печатью. Может ли кто-нибудь рассказать мне, почему моя программа просто перестает функционировать в данный момент, не отображая никаких ошибок?

EDIT: Я полагаю, что там может быть ошибка где-то в моем файле сервера, так вот класс:

public class Server { 

    private static int uid; 

    private ArrayList<ClientThread> clients; 
    private int port; 
    private boolean cont; 

    public Server(int p){ 
     port = p; 
     clients = new ArrayList<ClientThread>(); 
    } 

    public void start(){ 
     System.out.println("Started"); 
     cont = true; 
     try{ 
      ServerSocket srvr = new ServerSocket(port); 
      System.out.println("Declared socket"); 
      while(cont){ 
       Socket sk = srvr.accept(); 
       System.out.println("Socket accepted"); 

       if(!cont)break; 

       ClientThread t = new ClientThread(sk); 
       clients.add(t); 
       t.start(); 
      } 
      try{ 
       srvr.close(); 
       for(ClientThread t : clients){ 
        t.in.close(); 
        t.out.close(); 
        t.socket.close(); 
       } 
      }catch(Exception e){ 
       e.printStackTrace(); 
      } 
     }catch(Exception e){ 

      e.printStackTrace(); 
     } 
    } 

    private synchronized void broadcast(String msg){ 
     for(int i=clients.size(); --i >= 0;){ 
      ClientThread t= clients.get(i); 
       if(!t.writeMsg(msg)){ 
        clients.remove(i); 
       } 
     } 
    } 

    public static void main(String[] args){ 
     int portNum = 1500; 

     Server server = new Server(portNum); 
     server.start(); 
    } 

    class ClientThread extends Thread{ 
     Socket socket; 
     ObjectInputStream in; 
     ObjectOutputStream out; 
     String name; 
     int id; 
     Message m; 

     ClientThread(Socket s){ 
      id = ++uid; 
      socket = s; 
      try{ 
       System.out.println("Before"); 
       in = new ObjectInputStream(socket.getInputStream()); 
       out = new ObjectOutputStream(socket.getOutputStream()); 
       System.out.println("After"); 
      }catch(Exception e){ 
       e.printStackTrace();} 
     } 

     public void run(){ 
      boolean c = true; 
      while(c){ 
       try{ 
        m = (Message)in.readObject(); 
        switch(m.getType()){ 
        case 2: 
         broadcast(m.getMessage()); 
        } 
       }catch (Exception e){ 
        e.printStackTrace();} 
      } 
     } 

     public boolean writeMsg(String msg){ 
      if(!socket.isConnected()){ 
       return false; 
      } 
      try{ 
       out.writeObject(msg); 
      }catch(Exception e){ 
       e.printStackTrace();} 
      return true; 
     } 
    } 

} 

Хорошо, другую правку. Поэтому я добавил эти два println s в оператор try в конструкторе ClientThread, и, как и у клиента, он работает до тех пор, пока я не попытаюсь инициализировать потоки, а затем он просто остановится. Опять же, никаких ошибок, ничего; он просто полностью останавливается на своем пути. Я не могу понять, почему это происходит, но если это что-то значит, я использую среду Eclipse для ее запуска.

+0

Просто подсказка: две строки над той, которая печатает «Все объявленные», ничего не объявляют. – immibis

+0

Откуда вы знаете, что он не застрял в 'new Socket (server, port)'? – immibis

+0

@immibis Правильно, но изменение вывода на «Все назначенные». на самом деле не заставит код работать лучше. – user2649681

ответ

1

Я зацепил на этом в первый раз я использовал ObjectInputStream и ObjectOutputStream. В основе вашей проблемы лежит constructor ObjectInputStream. Конструктор будет читать из основного потока в попытке получить информацию заголовка, такую ​​как версия формата проводов.

Чтобы предотвратить бесконечный доступ вашего клиента и сервера к другому, чтобы отправить информацию сначала, вы должны инвертировать порядок входных и выходных потоков, а затем явно очистить выходной поток. Ниже при построении потоков на клиенте и сервере будет исправлена ​​ваша проблема:

out = new ObjectOutputStream(socket.getOutputStream()); 
out.flush(); 
in = new ObjectInputStream(socket.getInputStream());