简体   繁体   中英

The readObject() Method of objectOutputStream is not receiving the object written on the inputStream to the Client?

The aim is to transfer the coordinates from one Client(who is drawing) to all the Clients Connected to the Server and then draw on their respective Panels, but the readObject() in Client never seems to fetch the data. The Input Does go to the Server Properly but from Server, the Other CLients Couldn't Listen to it.

When using BufferedStream or DataInput/OutputStream any Other the input seems to lag or misbehaving. So preferring ObjectOutputStream. Snapshot of the Program.

The Client listens for the input in a background Thread listenData.

The Client Code -

public class Clients extends JFrame {

private static final long serialVersionUID = 1L;
private Coordinates crdntsToSend;
private Coordinates crdntsReceived;
private JPanel contentPane;
private Socket socket;
private ObjectOutputStream toServerPipe;
private ObjectInputStream fromServerPipe;
private JPanel paintPanel;

public Clients(String name,int port,String ip) {
    setResizable(false);
    setTitle("Skribbl");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(600,550);
    createConnection(ip,port);
    listen();
}

private void createConnection(String ip,int port)
{
    try {
        socket = new Socket(ip,port);
        toServerPipe = new ObjectOutputStream(socket.getOutputStream());
        fromServerPipe = new ObjectInputStream(socket.getInputStream());
        toServerPipe.flush();
        userInterfaceSetter();
    } catch (IOException e) {
        System.out.println("Port Not Found!!!");
        return;
    }
}

private void userInterfaceSetter()
{
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e1) {
        e1.printStackTrace();
    } 
    getContentPane().setLayout(null);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    GridBagLayout gbl_contentPane = new GridBagLayout();
    gbl_contentPane.columnWidths = new int[] {0, 0};
    gbl_contentPane.rowHeights = new int[]{0, 0, 0};
    gbl_contentPane.columnWeights = new double[]{1.0, Double.MIN_VALUE};
    gbl_contentPane.rowWeights = new double[]{1.0, 0.0, Double.MIN_VALUE};
    contentPane.setLayout(gbl_contentPane);
    
    paintPanel = new JPanel();
    paintPanel.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseClicked(MouseEvent e) {
            drawOnPanel(e.getX(),e.getY());
        }
    });
    paintPanel.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            drawOnPanel(e.getX(),e.getY());
        }
    });
    paintPanel.setBackground(new Color(175, 238, 238));
    GridBagConstraints gbcPaintPanel = new GridBagConstraints();
    gbcPaintPanel.insets = new Insets(10, 10, 10, 10);
    gbcPaintPanel.fill = GridBagConstraints.BOTH;
    gbcPaintPanel.gridx = 0;
    gbcPaintPanel.gridy = 0;

    contentPane.add(paintPanel, gbcPaintPanel);
    
    JLabel lblScore = new JLabel("Score: ");
    GridBagConstraints gbclblScore = new GridBagConstraints();
    gbclblScore.insets = new Insets(0, 0, 10, 0);
    gbclblScore.anchor = GridBagConstraints.WEST;
    gbclblScore.gridx = 0;
    gbclblScore.gridy = 1;
    contentPane.add(lblScore, gbclblScore);
}

private void drawOnPanel(int x,int y)
{
    Graphics g = paintPanel.getGraphics();
    g.fillOval(x, y, 7, 7);
    sendData(x,y);
}

private void sendData(int x, int y) {
    try {
        crdntsToSend = new Coordinates(x,y);
        toServerPipe.writeObject(crdntsToSend);
        toServerPipe.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
}
private void listen()
{
    SwingWorker<Void, String> listenData = new SwingWorker<Void, String>() {
        boolean go = true;
        String[] receivedData;
        String str;
        @Override
        protected Void doInBackground() throws Exception {
            while(go)
            {
                crdntsReceived = (Coordinates) fromServerPipe.readObject();
                str= crdntsReceived.toString();
                publish(str);
            }
            return null;
        }

        @Override
        protected void process(List<String> chunks) {
             receivedData = str.split(" ");
             drawOnPanel(Integer.parseInt(receivedData[0]),Integer.parseInt(receivedData[1]));
        }
        
    };
    listenData.execute();
}

}

ServerHandler Code(Server Thread) -

package theskribbl;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class HandleClient implements Runnable 
{
  private Socket[] socket;
  private ObjectInputStream fromClients;
  private ObjectOutputStream toClients;
  private static int count = 0;
  private int temp;
  public HandleClient(Socket[] socket, int count)
  {
  HandleClient.count = count;
  temp=count;
  this.socket=socket;
  try 
  {
      fromClients = new ObjectInputStream(socket[count].getInputStream());
      toClients = new ObjectOutputStream(socket[count].getOutputStream());
      toClients.flush();
  } 
  catch (IOException e) 
  {
        e.printStackTrace();
   }
   }
    @Override
    public void run() 
    {
    int i;
    Coordinates coordinate;
    while(true) 
    {
        i=0;
        try 
    {
          coordinate = (Coordinates) fromClients.readObject();
          System.out.println(coordinate.toString());
          while(i<=count) 
    {
              if(i!=temp)
              {
                    toClients = new ObjectOutputStream(socket[i].getOutputStream());
                    toClients.writeObject(coordinate);
                    toClients.flush();
              }
              i++;
          }
        }
        catch (Exception e) 
    {
            System.out.println("Something Went Wrong");
            return;
        }
    } 
    } 
    }

code of Client - https://repl.it/@GirirajSingh/skribbl#Clients.java

code for Logging into Client - https://repl.it/@GirirajSingh/skribbl#Login.java

code for Handling the Client(Server Side) - https://repl.it/@GirirajSingh/skribbl#HandleClient.java

code of Server - https://repl.it/@GirirajSingh/skribbl#ServerClass.java

ObjectOutputStream and ObjectInputStream constructor calls must be matched - when an ObjectOutputStream is created, it sends a header which must be received when creating an ObjectInputStream .

I have no time to study the code, but it looks like the output streams are being constructed in a loop every time something is being sent by the server. Are the clients reopening the input every time they received a coordinate?

Check the documentation of ObjectOutputStream and ObjectInputStream for better explanation. Better start with a (very) simple prototype: one server, one client, and just sending a couple of (test = fixed) coordinates.


There is probably an Exception being thrown by doInBackGround() (inside the SwingWorker )! It is advised to check for this by calling the get() method after the SwingWorker terminates (inside its overridden done() ) - this will thrown an ExecutionException if the computation threw an exception, which will have information about the Exception.

Add some code like the following to the SwingWorker :

@Override
protected void done() {
    try {
        get();
    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

ATTENTION: this code is not intended to solve the problem, only to show a possible error

The headers that you're saying is not matching, actually they are matching because they've been initialised via the same Socket. The same process works using DataOutputStream/DataInputStream(write()/read() ) but in this the data is getting leaked because if the mouse's dragged fast the data gets lost in between. so that's why i want to use read/writeObject() of ObjectOutputStream.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM