2016-04-25 2 views
0

Я работаю с классом TCPClient и классом TCPServer. Я создал программу рисования в своем TCPClient, а затем отправил на сервер информацию о точке (рисовании) и наоборот, чтобы все клиенты, работающие на сервере, работали на «том же» холсте.Функция рисования беспорядочна при создании соединения между сервером и клиентом

TCPServer:

public class TCPServer { 

    private static final int serverPort = 9000; 

    public static void main(String argv[]) throws Exception { 
     ServerSocket welcomeSocket = new ServerSocket(serverPort); 

     ArrayList<Point> completeDrawing = new ArrayList<>(); 
     ArrayList<Point> receivedList = new ArrayList<>(); 

     while (true) { 

      Socket connectionSocket = welcomeSocket.accept(); 
      ObjectInputStream inFromClient = new ObjectInputStream(connectionSocket.getInputStream()); 


      ObjectOutputStream outToClient = new ObjectOutputStream(connectionSocket.getOutputStream()); 

      receivedList.addAll((ArrayList<Point>) inFromClient.readObject()); 
      completeDrawing.addAll(receivedList); 
      receivedList.clear(); 

      outToClient.writeObject(completeDrawing); 

      connectionSocket.close(); 
     } 

    } 
} 

TCPClient:

public class TCPClient extends JPanel { 

    public static ArrayList<Point> location = new ArrayList<>(); 

    private JTextArea consoleOutput = new JTextArea(1,20); 

    public void addComponentToPane(Container pane) { 
     consoleOutput.setEditable(false); 
    } 

    public TCPClient() { 
     addMouseListener(new MouseAdapter() { 
      @Override 
      public void mousePressed(MouseEvent e) { 
       synchronized (location) { 
       location.add(e.getPoint()); 
       location.notify(); 
       } 
      } 
     }); 

     addMouseMotionListener(new MouseMotionAdapter() { 
      @Override 
      public void mouseDragged(MouseEvent e) { 
       synchronized (location) { 
       location.add(e.getPoint()); 
       location.notify(); 
       repaint(); 
       } 
      } 
     }); 

     setPreferredSize(new Dimension(800, 500)); 
     setBackground(Color.WHITE); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     synchronized (location) { 
      if(location.isEmpty()){ 
       return; 
      } 

      Point p = location.get(0); 
      for (int i = 1; i < location.size(); i++) { 
       Point q = location.get(i); 
       g.drawLine(p.x, p.y, q.x, q.y); 
       p = q; 
      } 
     } 
    } 

    public static void main(String argv[]) throws Exception { 

     InetAddress SERVERIP = InetAddress.getLocalHost(); 

     JFrame frame = new JFrame("Drawing with friends"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new TCPClient(), BorderLayout.CENTER); 

     JTextArea IPadress = new JTextArea(1,20); 
     IPadress.setEditable(false); 
     IPadress.append("DEVICE IP: " + SERVERIP.getHostAddress()); 
     frame.add(IPadress, BorderLayout.SOUTH); 

     frame.setSize(new Dimension(800,600)); 
     frame.setLocationRelativeTo(null); 
     frame.setResizable(false); 
     frame.setVisible(true); 

     while(true) { 
      synchronized (location) { 
       Socket clientSocket = new Socket("localhost", 9000); 

       ObjectOutputStream outToServer = new ObjectOutputStream(clientSocket.getOutputStream()); 
       ObjectInputStream inFromServer = new ObjectInputStream(clientSocket.getInputStream()); 

       outToServer.writeObject(location); 

       outToServer.flush(); 
       location.wait(); 

       location.addAll((ArrayList<Point>) inFromServer.readObject()); 
      } 
     } 
    } 
} 

С помощью этих классов, моя функция рисования путает. Это начинает отставать и заикание трудно, в то время как рисунок работает только с одной точки: enter image description here

Однако, если я закомментировать мой сервер для потока клиентов, он работает просто отлично (только в одном клиентском окне, конечно): enter image description here

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

+0

что именно вы прокомментировали? –

+0

@IvanZelenskyy //outToClient.writeObject(completeDrawing); – WONDERGG

+0

Я скопировал ваш код, и у меня он работает без латентности. Но что, по-видимому, сервер делает, чтобы я мог проверить, работает ли он правильно? –

ответ

0

Слишком много данных на клиенте, потому что данные в «чертежных» списках массивов (с обеих сторон) имеют много дубликатов. Перепишите код, чтобы добавить только новые точки в списки «location» и «fullDrawing», такие как:

ArrayList<Point> serverPoints = (ArrayList<Point>)inFromServer.readObject(); 
for(Point p : serverPoints){ 
    if(!location.contains(p)) location.add(p); 
} 
Смежные вопросы