Java从数据流切换到对象流
我正在建立一个4人网络扑克游戏。我首先创建一个运行游戏的游戏对象。它创建一个服务器对象。服务器对象产生4个线程,每个线程负责不同的套接字连接。然后游戏对象生成4个玩家对象。每个玩家对象都会有关于玩家的数据,但现在我只存储他们的输入和输出对象。播放器对象分别创建一个表,并将输入和输出连接信息传递给它们。表的Java从数据流切换到对象流,java,networking,Java,Networking,我正在建立一个4人网络扑克游戏。我首先创建一个运行游戏的游戏对象。它创建一个服务器对象。服务器对象产生4个线程,每个线程负责不同的套接字连接。然后游戏对象生成4个玩家对象。每个玩家对象都会有关于玩家的数据,但现在我只存储他们的输入和输出对象。播放器对象分别创建一个表,并将输入和输出连接信息传递给它们。表的对象是我的客户机。它们连接到服务器并来回发送信息。这个例子在我使用DataInputObjects/DataOutputObjects时起作用,但现在我已经将它们切换到ObjectInputOb
对象是我的客户机。它们连接到服务器并来回发送信息。这个例子在我使用DataInputObjects
/DataOutputObjects
时起作用,但现在我已经将它们切换到ObjectInputObjects
/ObjectOutputObjects
了,它生成了我的两个客户端(of table
),然后抛出一个异常。我知道我发送数据的方式有很多错误,我想在我能够发送对象之后再解决这个问题。我已经尝试过在输入对象之前创建输出对象,它给出了相同的错误。谢谢你的帮助
输出:
Starting server...
Connecting...
Server Started...
Connection successful
Connection from:/127.0.0.1
Connecting...
Connection successful
Connection from:/127.0.0.1
Connection from:/127.0.0.1
Connecting...
Connection successful
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream$BlockDataInputStream.readBlockHeader(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.refill(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.read(Unknown Source)
at java.io.DataInputStream.readUnsignedShort(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUnsignedShort(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readUTF(Unknown Source)
at java.io.ObjectInputStream.readUTF(Unknown Source)
at OFCTable.run(OFCTable.java:785)
at java.lang.Thread.run(Unknown Source)
游戏课
公开课游戏{
public static void main(String[] args) throws Exception {
Server server = new Server();
Thread thread = new Thread(server);
thread.start();
Player[] Players = new Player[4];
for(int i=0; i<4; i++ )
Players[i] = new Player(i+1);
}
}
OFCTable类(缩短,以便只列出需要知道的信息)
我从server类编写的惟一内容是UTF字符串
我怀疑您在包装套接字流一次且仅包装一次时不够小心。对于数据流,如果您不使用任何缓冲(这会影响性能),您可以多次包装它们
对于对象流,您必须小心地只包装一次流,并且只使用一次包装。您必须这样做,因为这些包装是有状态的,您不能随意混合它们
顺便说一句,如果你只使用readUTF/writeUTF,你只需要带缓冲区的数据流。“我知道我发送数据的方式有很多错误,我想在以后能够发送对象后解决这个问题。”.java:785
代码中的哪一行是table.java:785。很明显,您正在向流写入另一端不需要的内容。如果您告诉我们代码中的哪一行是table.java:785,可能会有所帮助。您正在尝试读取UTF字符串,而您很可能编写了其他类似writeObject的内容。@JimGarrison string message=in.readUTF()这是一条直线785@PeterLawrey我从server类编写的唯一内容是UTF StringsNB您应该在两端的ObjectInputStream
之前创建ObjectOutputStream
。这样,如果两端都以相反的方式执行,您就无法获得出现的死锁。我计划实现命令模式并发送命令objects在服务器和客户端之间,因此我确实需要对象流。而且我只包装了一次流。@bassxzero流损坏的另一个原因是试图写入或同时读取多个线程。即使您正在写入不同的套接字,也是这样吗?@bassxzero您可以在一个线程中读取,在另一个线程中写入。您可以使用ent线程在自己的套接字上没有问题。每个流一次只能由一个线程使用。
public class Server implements Runnable{
static ServerSocket serverSocket;
static Socket socket;
static ObjectOutputStream out;
static ObjectInputStream in;
static Users[] user = new Users[4];
public Server() throws Exception{
}
public void run() {
System.out.println("Starting server...");
try {
serverSocket= new ServerSocket(7777);
System.out.println("Server Started...");
while(true){
socket = serverSocket.accept();
for(int i =0;i<4;i++){
System.out.println("Connection from:" +socket.getInetAddress());
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
if(user[i]==null){
user[i]=new Users(out,in,user,i+1);
Thread thread = new Thread(user[i]);
thread.start();
break;
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class Users implements Runnable{
static private Deck cards = new Deck();
ObjectOutputStream out;
ObjectInputStream in;
Users[] user = new Users[4];
int Player;
public Users(ObjectOutputStream out, ObjectInputStream in,Users[] user,int Player){
this.out = out;
this.in = in;
this.user = user;
this.Player = Player;
cards.Shuffle();
}
public void run(){
while(true){
try {
String message = in.readUTF();
switch (message) {
case "1":
message = in.readUTF();
for(int i=0;i<4;i++){
if(user[i]!=null){
user[i].out.writeUTF("View");
user[i].out.writeUTF(message);
}
}
cards.Draw();
message = cards.getCurrent().toString();
break;
case "2":
message = "updatenow";
break;
case "Player":
message = "Player";
in.readUTF();
message = "" + Player;
break;
case "CC":
message = "CC";
for(int i=0;i<4;i++){
if(user[i]!=null){
user[i].out.writeUTF(message);
}
}
message = cards.getCurrent().toString();
break;
default:
break;
}
for(int i=0;i<4;i++){
if(user[i]!=null){
user[i].out.writeUTF(message);
}
}
} catch (IOException e) {
e.printStackTrace();
this.in = null;
this.out = null;
}
}
}
}
public class Player {
Deck deck = new Deck();
ObjectInputStream in;
ObjectOutputStream out;
Socket socket;
int Player=0;
public Player(int play) throws Exception{
this.Player = play;
System.out.println("Connecting...");
socket=new Socket("localhost",7777);
System.out.println("Connection successful");
//in = new ObjectInputStream(socket.getInputStream());
//out = new ObjectOutputStream(socket.getOutputStream());
OFCTable input = new OFCTable(socket,Player);
Thread thread = new Thread(input);
thread.start();
}
}
public class OFCTable extends javax.swing.JFrame implements MouseListener, Runnable {
ObjectInputStream in;
ObjectOutputStream out;
String message;
String CurrentCard;
private int Player = 0;
private int turn = 1;
public OFCTable(Socket soc,int play) throws IOException {
this.in = new ObjectInputStream(soc.getInputStream());
this.out = new ObjectOutputStream(soc.getOutputStream());
this.Player = play;
//this.ObjOut = out;
initComponents();
setVisible(true);
createComponentMap();
}
public OFCTable(ObjectInputStream in,ObjectOutputStream out,int play) {
System.out.println("here");
this.in = in;
this.out = out;
this.Player = play;
initComponents();
setVisible(true);
createComponentMap();
}
public void run() {
try {
out.writeUTF("CC");
} catch (IOException e1) {
e1.printStackTrace();
}
while(true){
try {
String message = in.readUTF();
switch (message) {
case "updatenow":
CurrentCard = message;
Update();
break;
case "View":
message = in.readUTF();
setComponentByName(message.split(" ")[1],message.split(" ")[0]);
message = in.readUTF();
CurrentCard = message;
turn = (turn + 1) % 5;
if (turn == 0) turn = 1;
Update();
break;
case "CC":
message = in.readUTF();
CurrentCard = message;
Update();
break;
case "Player":
message = in.readUTF();
CurrentCard = message;
Update();
break;
default:
CurrentCard = message;
Update();
break;
}
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
}