[英]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
. ObjectOutputStream
和ObjectInputStream
构造函数调用必须匹配 - 创建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.查看
ObjectOutputStream
和ObjectInputStream
的文档以获得更好的解释。 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.