简体   繁体   English

objectOutputStream 的 readObject() 方法没有接收到写入到 Client 的 inputStream 上的 object?

[英]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.目的是将坐标从一个客户端(正在绘制)传输到连接到服务器的所有客户端,然后在它们各自的面板上绘制,但客户端中的 readObject() 似乎永远不会获取数据。 The Input Does go to the Server Properly but from Server, the Other CLients Couldn't Listen to it.输入正确执行 go 到服务器,但从服务器,其他客户端无法收听。

When using BufferedStream or DataInput/OutputStream any Other the input seems to lag or misbehaving.当使用 BufferedStream 或 DataInput/OutputStream any Other 时,输入似乎滞后或行为不端。 So preferring ObjectOutputStream.所以更喜欢ObjectOutputStream。 Snapshot of the Program.程序快照。

The Client listens for the input in a background Thread listenData.客户端在后台线程listenData 中侦听输入。

The Client Code -客户代码 -

public class Clients extends JFrame {公共 class 客户扩展 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) - ServerHandler 代码(服务器线程) -

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客户代码 - https://repl.it/@GirirajSingh/skribbl#Clients.java

code for Logging into Client - https://repl.it/@GirirajSingh/skribbl#Login.java登录客户端的代码 - https://repl.it/@GirirajSingh/skribbl#Login.java

code for Handling the Client(Server Side) - https://repl.it/@GirirajSingh/skribbl#HandleClient.java处理客户端(服务器端)的代码 - https://repl.it/@GirirajSingh/skribbl#HandleClient.java

code of Server - https://repl.it/@GirirajSingh/skribbl#ServerClass.java服务器代码 - 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 . ObjectOutputStreamObjectInputStream构造函数调用必须匹配 - 创建ObjectOutputStream时,它会发送 header ,创建ObjectInputStream时必须接收该 header 。

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.我没有时间研究代码,但看起来 output 流在每次服务器发送某些内容时都在循环中构建。 Are the clients reopening the input every time they received a coordinate?客户每次收到坐标时是否都会重新打开输入?

Check the documentation of ObjectOutputStream and ObjectInputStream for better explanation.查看ObjectOutputStreamObjectInputStream的文档以获得更好的解释。 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 )! doInBackGround() (在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.建议在SwingWorker终止后(在其覆盖的done()内)调用get()方法来检查这一点 - 如果计算抛出异常,这将抛出ExecutionException ,其中将包含有关异常的信息。

Add some code like the following to the SwingWorker :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.使用 DataOutputStream/DataInputStream(write()/read() ) 进行相同的过程,但是在此过程中,数据会泄漏,因为如果鼠标快速拖动,则数据会在两者之间丢失。 so that's why i want to use read/writeObject() of ObjectOutputStream.所以这就是为什么我想使用 ObjectOutputStream 的 read/writeObject()。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用readObject()接收对象时,出现NoClassDefFoundException - NoClassDefFoundException when receiving object with readObject() ObjectOutputStream, readObject 只从序列化文件中读取第一个对象 - ObjectOutputStream, readObject only reads first object from serialized file readObject()方法不打印对象 - readObject() method not printing object 为什么 ObjectOutputStream.readObject() 返回 Object 类型的对象而不是我编写它的类型的对象? - Why does ObjectOutputStream.readObject() return object of type Object and not object of type I wrote it in? 仅通过一个客户端通过ObjectOutputStream发送对象 - send an object through ObjectOutputStream only one client readObject方法只读取它接收的第一个对象 - readObject method only reads the first object it receives 在附加模式下读取由ObjectOutputStream编写的目标文件(多次关闭) - Reading an object file written by ObjectOutputStream in append mode (multiple closings) 为什么ObjectOutputStream.readObject()访问MyClass.readObject() - Why does ObjectOutputStream.readObject() access MyClass.readObject() 使用readObject()接收对象时发生java.lang.ClassCastException - java.lang.ClassCastException when receiving object with readObject() ReadObject方法 - ReadObject Method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM