Hello,
I am currently testing some networking with java as im going to start implementing it into XNA soon.
So far, I've had quite a bit of success, but im starting from scratch and couldn't find enough examples, so i did some research on network loops, etc..
anyways, I'm getting a weird error, I'll put my code into a couple of code blocks below, as well as the error I'm recieving at the end.
--------------------THE CLIENT THREAD ON SERVER SIDE --------------------
package OnlineGameTest; //The client that will communicating to the server. import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.*; import java.util.ArrayList; import javax.swing.*; public class ClientGame extends JComponent implements ActionListener, KeyListener { Dimension clientBounds = new Dimension(600, 600); int x = 100; int y = 100; int moveSpeed = 5; Timer time; Rectangle playerSize = new Rectangle(32, 32); Socket serverSocket; ObjectOutputStream os; ObjectInputStream is; PlayerData player = new PlayerData(100, 100, (byte) 0); ArrayList<Byte> keyBuffer = new ArrayList<Byte>(); ArrayList<PlayerData> players = new ArrayList<PlayerData>(); int numbPlayers = 0; boolean Up = false; boolean Down = false; boolean Left = false; boolean Right = false; // ----KEY CODES FOR BUFFER public final byte UP_PRESSED = 10; public final byte DOWN_PRESSED = 11; public final byte LEFT_PRESSED = 12; public final byte RIGHT_PRESSED = 13; public final byte UP_RELEASED = 14; public final byte DOWN_RELEASED = 15; public final byte LEFT_RELEASED = 16; public final byte RIGHT_RELEASED = 17; Runnable networkLoop = new Runnable() { @Override public void run() { try { while (true) { System.out.println("im in the loop!"); if (keyBuffer.size() > 0) { // System.out.println("Keybuffer size: " + // keyBuffer.size()); for (int i = 0; i < keyBuffer.size(); i++) { if (keyBuffer.get(i) != null) { switch (keyBuffer.get(i)) { case UP_PRESSED: os.writeByte(UP_PRESSED); System.out.println("sent up!"); break; case UP_RELEASED: os.writeByte(UP_RELEASED); break; case DOWN_PRESSED: os.writeByte(DOWN_PRESSED); break; case DOWN_RELEASED: os.writeByte(DOWN_RELEASED); break; case LEFT_PRESSED: os.writeByte(LEFT_PRESSED); break; case LEFT_RELEASED: os.writeByte(LEFT_RELEASED); break; case RIGHT_PRESSED: os.writeByte(RIGHT_PRESSED); break; case RIGHT_RELEASED: os.writeByte(RIGHT_RELEASED); break; default: System.out .println("At least im doing something"); break; } } os.flush(); keyBuffer.clear(); } } else { os.writeByte(0); // tell it at least connected os.flush(); } byte packetSize = is.readByte(); System.out.println(" : " + packetSize); for (int i = 0; i < packetSize; i++) { int theByte = is.read(); System.out.println("the byte: " + theByte); switch (theByte) { case 1: System.out.println((String) is.readObject()); break; case 2: System.out.println("got player coords"); player.x = is.readFloat(); player.y = is.readFloat(); break; case 3: int numbPlayers = is.readByte(); for (int ii = 0; ii < numbPlayers; ii++) { byte id = is.readByte(); int playerIndex = -1; for (int iii = 0; iii < players.size(); iii++) { if (players.get(iii).ID == id) { playerIndex = ii; players.get(iii).x = is.readFloat(); players.get(iii).y = is.readFloat(); break; } } if (playerIndex == -1) { numbPlayers += 1; float x = is.readFloat(); float y = is.readFloat(); players.add(new PlayerData(x, y, id)); } } default: System.out.println("shootin blanks"); break; } } } } catch (Exception e) { e.printStackTrace(); } } }; Runnable send = new Runnable() { @Override public void run() { try { while (true) { } } catch (Exception e) { e.printStackTrace(); } } }; public ClientGame() { setVisible(true); setPreferredSize(clientBounds); setFocusable(true); requestFocus(); } public void Initialize() { addKeyListener(this); time = new Timer(17, this); time.start(); requestFocus(); setUpConnection("127.0.0.1", 40046); } public void paintComponent(Graphics g) { // TODO Auto-generated method stub Graphics2D g2 = (Graphics2D) g; g2.setColor(Color.orange); g2.fillRect(0, 0, getWidth(), getHeight()); g2.setColor(Color.black); g2.fillRect((int) player.x, (int) player.y, playerSize.width, playerSize.height); g2.setColor(Color.GRAY); for (int i = 0; i < players.size(); i++) { g2.fillRect((int) players.get(i).x, (int) players.get(i).y, playerSize.width, playerSize.height); g2.drawString(String.valueOf((int) players.get(i).ID), (int) players.get(i).x, (int) players.get(i).y); } } @Override public void actionPerformed(ActionEvent e) { if (e.getSource() == time) { repaint(); } } @Override public void keyTyped(KeyEvent e) { } @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP && !Up) { Up = true; keyBuffer.add(UP_PRESSED); } if (e.getKeyCode() == KeyEvent.VK_DOWN && !Down) { Down = true; keyBuffer.add(DOWN_PRESSED); } if (e.getKeyCode() == KeyEvent.VK_RIGHT && !Right) { Right = true; keyBuffer.add(RIGHT_PRESSED); } if (e.getKeyCode() == KeyEvent.VK_LEFT && !Left) { Left = true; keyBuffer.add(LEFT_PRESSED); } } @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) { Up = false; keyBuffer.add(UP_RELEASED); } if (e.getKeyCode() == KeyEvent.VK_DOWN) { Down = false; keyBuffer.add(DOWN_RELEASED); } if (e.getKeyCode() == KeyEvent.VK_RIGHT) { Right = false; keyBuffer.add(RIGHT_RELEASED); } if (e.getKeyCode() == KeyEvent.VK_LEFT) { Left = false; keyBuffer.add(LEFT_RELEASED); } } public void setUpConnection(String ServerName, int port) { try { serverSocket = new Socket(ServerName, port); os = new ObjectOutputStream(serverSocket.getOutputStream()); is = new ObjectInputStream(serverSocket.getInputStream()); Thread NetworkLoop = new Thread(networkLoop); NetworkLoop.start(); } catch (Exception e) { e.printStackTrace(); } } }
----------------THE CLIENT THREAD ON THE SERVER SIDE -----------------
package OnlineGameTest; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import java.util.ArrayList; public class ClientHandler { public static Socket socket; public static boolean Connected; ObjectInputStream is; ObjectOutputStream os; PlayerData player; public static int clientID; boolean moveUp = false; boolean moveDown = false; boolean moveRight = false; boolean moveLeft = false; float playerSpeed = 5; float oldX = 0f; float oldY = 0f; ArrayList<Byte> commandBuffer = new ArrayList<Byte>(); ArrayList<ClientHandler> tempClients = new ArrayList<ClientHandler>(); public ClientHandler(Socket clientSocket, int ID) { this.socket = clientSocket; player = new PlayerData(20f, 20f, (byte) ID); Connected = true; clientID = ID; try { is = new ObjectInputStream(clientSocket.getInputStream()); os = new ObjectOutputStream(clientSocket.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } Thread Networking = new Thread(networkLoop); Networking.start(); } public void Update() { // System.out.println("playerX: " + player.x + " PlayerY: " + player.y); if (moveUp) { player.y -= playerSpeed; } if (moveDown) { player.y += playerSpeed; } if (moveLeft) { player.x -= playerSpeed; } if (moveRight) { player.x += playerSpeed; } } Runnable networkLoop = new Runnable() { public void run() { while (Connected) { try { Byte tempByte; if ((tempByte = is.readByte()) != null) { // System.out.println("Byte read: " + tempByte); switch (tempByte) { case GameServer.UP_PRESSED: System.out.println("Recieved Up"); moveUp = true; break; case GameServer.UP_RELEASED: System.out.println("Recieved up released!"); moveUp = false; break; case GameServer.DOWN_PRESSED: moveDown = true; break; case GameServer.DOWN_RELEASED: moveDown = false; break; case GameServer.LEFT_PRESSED: moveLeft = true; break; case GameServer.LEFT_RELEASED: moveLeft = false; break; case GameServer.RIGHT_PRESSED: moveRight = true; break; case GameServer.RIGHT_RELEASED: moveRight = false; System.out.println("got right released"); break; default: break; } } calculateCommands(); os.writeByte(commandBuffer.size()); // tells the client how // big of a packet to // read for (int i = 0; i < commandBuffer.size(); i++) { switch (commandBuffer.get(i)) { case 0: os.writeByte(0); case 1: os.writeByte(1); os.writeObject("clientID: " + clientID + "is Connected"); break; case 2: os.writeByte(2); os.writeFloat(player.x); os.writeFloat(player.y); oldX = player.x; oldY = player.y; break; case 3: os.writeByte(3); tempClients.clear(); for(int ii = 0;ii < GameServer.Clients.size();ii++){ // calculate which need to be updated on client if(GameServer.Clients.get(ii).clientID != clientID){ tempClients.add(GameServer.Clients.get(ii)); } } os.writeByte(tempClients.size()); for(int ii = 0; ii < tempClients.size();ii++){ os.writeByte(tempClients.get(ii).clientID); os.writeFloat(tempClients.get(ii).player.x); os.writeFloat(tempClients.get(ii).player.y); } case -1: System.out.println("WTF"); break; default: break; } } commandBuffer.clear(); os.flush(); } catch (Exception e) { e.printStackTrace(); } } } }; public void calculateCommands() { if (player.x != oldX || player.y != oldY) { commandBuffer.add((byte) 2); } else { commandBuffer.add((byte) 0); } ; if (GameServer.Clients.size() - 1 > 0) { commandBuffer.add((byte) 3); } } }
-----------------GAME SERVER ------------------
package OnlineGameTest; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; import java.net.*; import java.util.ArrayList; import javax.swing.Timer; public class GameServer{ int port = 40046; ServerSocket serverIO; ArrayList<Socket> clientSockets = new ArrayList<Socket>(); ObjectOutputStream os; ObjectInputStream is; Timer time; int numbClients = 0; public static final int MAX_CLIENTS = 10; public static ArrayList<ClientHandler> Clients = new ArrayList<ClientHandler>(); //--- KEYBUFFER CODES public static final byte UP_PRESSED = 10; public static final byte DOWN_PRESSED = 11; public static final byte LEFT_PRESSED = 12; public static final byte RIGHT_PRESSED = 13; public static final byte UP_RELEASED = 14; public static final byte DOWN_RELEASED = 15; public static final byte LEFT_RELEASED = 16; public static final byte RIGHT_RELEASED = 17; public static void main(String[] args){ new GameServer(); } public GameServer() { Initialize(); } public Runnable acceptConnections = new Runnable(){ @Override public void run() { try{ System.out.println("Waiting for clients..."); while(true){ Socket temp = new Socket(); temp = serverIO.accept(); System.out.println(": " + Clients.size()); Clients.add(new ClientHandler(temp,Clients.size() + 1)); System.out.println("User Connected: " + temp.toString() + " ID: " + Clients.get(Clients.size()-1).clientID); } } catch(Exception e){ e.printStackTrace(); } } }; public Runnable UpdateRun = new Runnable(){ @Override public void run() { time = new Timer(16,new ActionListener(){ @Override public void actionPerformed(ActionEvent e) { if(e.getSource() == time){ Update(); } } }); time.start(); } }; public void Initialize() { try{ serverIO = new ServerSocket(port); Thread runAccepter = new Thread(acceptConnections); runAccepter.start(); Thread startUpdate = new Thread(UpdateRun); startUpdate.start(); } catch(Exception e){ e.printStackTrace(); } } public void Update(){ for(int i = 0;i<Clients.size();i++){ if(Clients.get(i) != null){ Clients.get(i).Update(); } } } }
Everything was working up well until i started implementing the code for the 3rd case statement for sending packets / recieving packets, from client handler to client game. I can't seem to fix that.
this is the error that comes up, with some bug fixing println's i've included.
im in the loop! : 1 the byte: 2 got player coords im in the loop! : 1 the byte: 0 shootin blanks im in the loop! : 1 the byte: -1 shootin blanks im in the loop! java.io.EOFException at java.io.ObjectInputStream$BlockDataInputStream.readByte(ObjectInputStream.java:2745) at java.io.ObjectInputStream.readByte(ObjectInputStream.java:913) at OnlineGameTest.ClientGame$1.run(ClientGame.java:91) at java.lang.Thread.run(Thread.java:722)
Any tips regarding my code would be appreciated as well as the fix for this code!
I'll attach the code itself aswell if anyone wants to take a go.