2015-04-02 2 views
-2

Итак, у меня возникли проблемы с работой моего кода, поэтому я сделал упрощенную версию своей программы, чтобы выяснить, что происходит, но я все еще озадачен.Непредвиденные прерывания ввода/вывода в многопоточных программах

Вот программа:

Это код сервера:

public class Server{ 

    private ServerSocket server; 
    private Socket connection; 
    private DatagramSocket server_socket; 
    String compString = ""; 
    public static List<String> messages = Collections.synchronizedList(new ArrayList<String>()); 
    public static List<DatagramPacket> packets = Collections.synchronizedList(new ArrayList<DatagramPacket>()); 


    public Server() 
    {    
    } 

    public void startRunning() 
    { 
      try 
      { 
       server_socket = new DatagramSocket(9876);  
       receiveAndSend();    
      }catch(Exception e) 
      { 
       System.out.println("Exception caught"); 
      } 
    } 

    public void receiveAndSend() 
    { 
     Thread thread1 = new Thread() 
     { 
      public void run() 
      { 
       try{ 
       while(true) 
       { 
        byte[] buffer = new byte[3000]; 
        DatagramPacket request = new DatagramPacket(buffer, buffer.length); 
        server_socket.receive(request); 
        String mess = new String(request.getData());       
        synchronized(messages) 
        { 
         if(!messages.contains(mess) && !packets.contains(request)) 
         {        
          addMessage(mess); 
          addPacket(request);        
          System.out.println("added: " + mess);    
         }    
        }      
       } 
       }catch(Exception e) 
       { 
        System.out.println("Exception caught"); 
       }   
      }    
     }; 
     thread1.start();    
     Thread thread2 = new Thread() 
     {  
      public void run() 
      { 
       try 
       { 
        while(true) 
        { 
         Thread.sleep(6000);   
         System.out.println("the list contains");        
         synchronized(messages) 
         { 
          compString = "";      
          for (String st : messages) 
          {  
           System.out.println(st); 
          } 
          System.out.println("!!!!!!!!!!!!!!!!!!");  

          if(!messages.isEmpty()) 
          { 

           System.out.println(messages.size());          

           for(int i=0; i< messages.size(); i++) 
           {     
            compString += messages.get(i); 
            compString += "-"; 

           }               
          }        
         }        
         System.out.println("final string is:" + compString + "\n");      
         for(DatagramPacket pack: packets) 
         { 
          try 
          {     
           InetAddress add = pack.getAddress(); 
           int port = pack.getPort(); 

           byte[] tbuffer = compString.getBytes(); 
           DatagramPacket reply = new DatagramPacket(tbuffer, tbuffer.length, add, port); 
           server_socket.send(reply); 
          }catch(Exception e) 
          { 
           System.out.println("Exception caught"); 
          } 

         }  
        }     

       }catch(Exception e) 
       { 

       }   
      }    
     };    
     thread2.start();  
    } 

    public synchronized void addMessage(String mess) 
    {  
     messages.add(mess); 
    } 
    public synchronized void addPacket(DatagramPacket packet) 
    { 
     packets.add(packet); 
    }  
} 

Это код клиента:

public class Client { 

public String message; 
public int port; 
public int server = 9876; 

public void Client(String message) 
{ 
    this.message = message; 
} 

public void startRunning() 
{ 
     serverStart(); 
} 


public void serverStart() 
{ 
    Thread thread1 = new Thread() 
    {  
     public void run() 
     { 
      try{       
       DatagramSocket ssocket = new DatagramSocket(port);    
      while(true) 
      {     
        Thread.sleep(5000); 
        byte [] m =message.getBytes(); 
        InetAddress hhost = InetAddress.getByName("127.0.0.1"); //won't be always localh 

        DatagramPacket request = new DatagramPacket(m, m.length, hhost, server);       
        ssocket.send(request); 

        System.out.println("sending: " + message + "\n"); 

        byte[] buffer = new byte[2000]; 
        DatagramPacket reply = new DatagramPacket(buffer, buffer.length);      
        ssocket.receive(reply); 

        String receivedString = new String(reply.getData()); 

        System.out.println("receivedString : " + receivedString); 
        if(receivedString != null && !receivedString.isEmpty()) 
        { 


        }     

      } 
      }catch(Exception e) 
      { 
       System.out.println("Exception caught"); 
      } 


     } 
    }; 

    thread1.start();   

} 

public String[] convertStringToArray(String tstring) 
{ 
    tstring.trim(); 

    String[] sarray = tstring.split("-"); 

    return sarray; 
} 

}

Вы нужны эти 3 для запуска код:

public class ServerTest { 

    public static void main(String[] args) 
    { 
     Server s = new Server(); 
     s.startRunning(); 
    } 

} 

public class ClientTest2 { 

    public static void main(String[] args) 
    { 
     Client myclient = new Client(); 
     myclient.message = "Hello"; 
     myclient.port = 6965; 
     myclient.startRunning();    

    } 

} 

public class ClientTest { 

    public static void main(String[] args) 
    { 
     Client myclient = new Client(); 
     myclient.message = "Kitty"; 
     myclient.port = 6646; 
     myclient.startRunning(); 

    }   

} 

я получаю следующий результат, когда я бегу:

added: Helloadded: Kittythe list contains 
Hello2 
final string is:Hellothe list contains 
Hello 
!!!!!!!!!!!!!!!!!! 
2 
final string is:Hello 
the list contains 
Hello 
!!!!!!!!!!!!!!!!!! 

Проблема заключается в том, что: 1) Println иногда прерывается и никогда не работает, в выводе выше мы видим, что линия !!!! !!!!!!!!!! иногда не распечатывается. 2) Некоторые элементы в Arraylist не добавляются или не печатаются.

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

+4

(Не по теме, но связанный с получением лучшей помощи): одна пустая строка достаточно пробела - для лучшей помощи, форматируйте свой код, чтобы мы могли его прочитать. –

+0

'catch (исключение e) { }' проблема. Просто подумайте об этом ... – Holger

+0

нет, это не так. Я удалил операторы печати внутри блока catch, потому что я хотел посмотреть, изменится ли поведение. Я добавил утверждения назад некоторое время назад, и результат не изменился вообще. – jarvan

ответ

0

Вы не правильно сериализуете/десериализируете свои строки.

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

String receivedString = new String(reply.getData(), 0, reply.getLength(), "UTF-8"); 

В клиенте нужно указать кодировку использовать для сериализации Струнные:

byte[] m = message.getBytes("UTF-8"); 

Кроме того, DatagramPacket.equals() делает только ссылки сравнения (т.е. он будет возвращать только справедливо, если при передаче ссылки на себя, это не сравнение данных в другом пакете с его собственным), так !packets.contains(request) будет всегдабудь настоящим.

+0

Но кажется, что у arraylist только один элемент, поток прерывается или что-то такое, или это просто ввод-вывод, потому что я не получаю никакого исключения? – jarvan

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