0

I'm building a 4 player network poker game. I first create a game object which runs the game. It creates a server object. The server object spawns 4 threads each one will take care of a different socket connection. The Game object then spawns 4 player objects. Each player object will have data about the players, but for now I'm only storing their input and output objects. The player objects each create a OFCTable and passes them the input and output connection information. The OFCTable objects are my clients. They connect to the server and send info back and forth. This example was working when i was using DataInputObjects/DataOutputObjects, but now that I have switched them to ObjectInputObjects/ObjectOutputObjects it spawns 2 of my clients(OFCTable) then throws and AC exception. I understand there is a lot wrong with the way I send data and I want to fix that later after I'm able to send objects. I have already tried creating my output objects before my input objects and it gives the same error. Thanks for your help

Output:

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)

Game Class public class Game {

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

    }

}

Server Class

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

        }


    }
}

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

       }   

}

OFCTable Class (Shortened so that only need to know info is listed)

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

        }

    }   
bassxzero
  • 4,838
  • 22
  • 34
  • _" I understand there is a lot wrong with the way I send data and I want to fix that later after I'm able to send objects"_. You are correct that this code is a mess. Clearly you are writing something to the stream that is not expected at the other end. It might help if you told us which line was `OFCTable.java:785` in the code. – Jim Garrison Jan 08 '14 at 17:45
  • You are attempting to read a UTF string when most likely you wrote something else like writeObject. – Peter Lawrey Jan 08 '14 at 17:56
  • @JimGarrison String message = in.readUTF(); is line 785 – bassxzero Jan 08 '14 at 18:04
  • @PeterLawrey the only thing i write from the server class are UTF Strings – bassxzero Jan 08 '14 at 18:05
  • NB you should create the `ObjectOutputStream` before the `ObjectInputStream` at both ends. That way you cannot get the deadlock that arises if both ends do it the other way around. – user207421 Jan 08 '14 at 23:05

1 Answers1

1

the only thing i write from the server class are UTF Strings

I suspect you are not being careful about wrapping your Socket's Stream once and only once. With Data Stream you could get away with wrapping them more than once if you didn't use any buffering (which is a performance hit)

With Object Stream you must be careful to wrap the streams only once and only use that one wrapping. You have to do this because these wrappers are stateful and you can't just mix them how you like.

BTW If you only use readUTF/writeUTF you only need Data Streams with buffers.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • I plan to implement the command pattern and send command objects between the server and client so i do need Object Streams. Also I'm only wrapping my streams once. – bassxzero Jan 08 '14 at 18:45
  • @bassxzero Another cause of stream corruption is attempting to write, or read in multiple threads at once. – Peter Lawrey Jan 08 '14 at 19:04
  • Is this the case even if you are writing to different sockets? – bassxzero Jan 08 '14 at 19:20
  • @bassxzero You can read in one thread and write in another. You can use different thread on their own sockets no problem. Each stream can only be used by one thread at a time. – Peter Lawrey Jan 08 '14 at 19:31