Java从数据流切换到对象流

Java从数据流切换到对象流,java,networking,Java,Networking,我正在建立一个4人网络扑克游戏。我首先创建一个运行游戏的游戏对象。它创建一个服务器对象。服务器对象产生4个线程,每个线程负责不同的套接字连接。然后游戏对象生成4个玩家对象。每个玩家对象都会有关于玩家的数据,但现在我只存储他们的输入和输出对象。播放器对象分别创建一个表,并将输入和输出连接信息传递给它们。表的对象是我的客户机。它们连接到服务器并来回发送信息。这个例子在我使用DataInputObjects/DataOutputObjects时起作用,但现在我已经将它们切换到ObjectInputOb

我正在建立一个4人网络扑克游戏。我首先创建一个运行游戏的游戏对象。它创建一个服务器对象。服务器对象产生4个线程,每个线程负责不同的套接字连接。然后游戏对象生成4个玩家对象。每个玩家对象都会有关于玩家的数据,但现在我只存储他们的输入和输出对象。播放器对象分别创建一个表,并将输入和输出连接信息传递给它们。表的
对象是我的客户机。它们连接到服务器并来回发送信息。这个例子在我使用
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);
                }

        }

    }