Java从DataStreams切换到ObjectStreams

时间:2014-01-08 17:23:02

标签: java networking

我正在建立一个4人网络扑克游戏。我首先创建一个运行游戏的游戏对象。它创建一个服务器对象。服务器对象产生4个线程,每个线程将处理不同的套接字连接。然后Game对象产生4个玩家对象。每个玩家对象都会有关于玩家的数据,但是现在我只存储他们的输入和输出对象。每个播放器对象创建一个OFCTable并传递输入和输出连接信息。 OFCTable个对象是我的客户。它们连接到服务器并来回发送信息。这个示例在我使用DataInputObjects / DataOutputObjects时正常工作,但现在我已将它们切换为ObjectInputObjects / ObjectOutputObjects,它会产生2个客户端{{1}然后抛出和AC异常。我知道我发送数据的方式有很多问题,我想在以后能够发送对象之后解决这个问题。我已经尝试在输入对象之前创建输出对象,它会产生相同的错误。谢谢你的帮助

输出:

OFCTable

游戏类     公共课游戏{

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);

    }

}

玩家类

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;
            }

        }


    }
}

OFCTable Class(缩短以便只列出需要知道的信息)

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();             

       }   

}

1 个答案:

答案 0 :(得分:1)

  

我从服务器类写的唯一东西是UTF Strings

我怀疑你没有小心一次只包装你的Socket's Stream。使用数据流,如果您不使用任何缓冲(这会影响性能),您可以多次包装它们

使用对象流,您必须小心只将流包裹一次,并且只使用那个包裹。你必须这样做,因为这些包装器是有状态的,你不能只是按你喜欢的方式混合它们。

BTW如果你只使用readUTF / writeUTF,你只需要带有缓冲区的数据流。