I want to send some objects using network. My network I made it using DatagramSocket, DatagramPacket, ByteArrayInputStream, ObjectInputStream, ByteArrayOutputStream and ObjectOutputStream.
When I was trying to send an object using network I got java.io.EOFException and when I handled this exception using try and catch I lost my object.
Server Side
public class GameServer extends Thread {
private DatagramSocket socket;
private DatagramPacket packet;
private byte[] data;
private ByteArrayInputStream bais;
private ObjectInputStream ois;
private ByteArrayOutputStream baos;
private ObjectOutputStream oos;
private Game game;
public GameServer() {
try {
this.socket = new DatagramSocket(1331);
}
catch (SocketException e) {
e.printStackTrace();
}
start();
}
#Override
public void run() {
while (true) {
data = new byte[6400];
packet = new DatagramPacket(data, data.length);
Object object = receive();
if (object instanceof String) {
String message = (String) object;
System.out.println("CLIENT [ " + packet.getAddress().getHostAddress() + " : " + packet.getPort() + " ] >> " + message.trim());
if (message.equalsIgnoreCase("start")) {
game = new Game("Tankies", 1200, 700);
sendObject(game);
}
}
else if (object instanceof State) {
System.out.println("got state");
}
else if (object instanceof Player)
System.out.println("hi player");
}
}
private Object receive() {
bais = new ByteArrayInputStream(data);
try {
socket.receive(packet);
ois = new ObjectInputStream(new BufferedInputStream(bais));
return ois.readObject();
} catch (EOFException e) {
System.out.println("SERVER Got EOFException");
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
private void sendData(byte[] data, InetAddress ipAddress, int port) {
DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress, port);
try {
this.socket.send(packet);
}
catch (IOException e) {
e.printStackTrace();
}
}
private void sendObject(Object object) {
baos = new ByteArrayOutputStream(6400);
oos = null;
try {
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
}
catch (IOException e) {
e.printStackTrace();
}
sendData(baos.toByteArray(), packet.getAddress(), packet.getPort());
}
}
Client Side
public class GameClient extends Thread implements Serializable {
private InetAddress ipAddress;
private transient DatagramSocket socket;
private transient DatagramPacket packet;
private byte[] data;
private transient ByteArrayInputStream bais;
private transient ObjectInputStream ois;
private transient ByteArrayOutputStream baos;
private transient ObjectOutputStream oos;
private Game game;
public GameClient(String ipAddress) {
try {
this.socket = new DatagramSocket();
}
catch (SocketException e) {
e.printStackTrace();
}
try {
this.ipAddress = Inet4Address.getByName(ipAddress);
}
catch (UnknownHostException e) {
e.printStackTrace();
}
start();
}
#Override
public void run() {
while (true) {
data = new byte[6400];
packet = new DatagramPacket(data, data.length);
Object object = receive();
if (object instanceof String) {
System.out.println("SERVER >> " + object);
}
else if (object instanceof Game) {
this.game = (Game) object;
this.game.setClient(this);
this.game.start();
}
}
}
private Object receive() {
bais = new ByteArrayInputStream(data);
try {
socket.receive(packet);
ois = new ObjectInputStream(new BufferedInputStream(bais));
return ois.readObject();
}
catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
private void sendData(byte[] data) {
DatagramPacket packet = new DatagramPacket(data, data.length, ipAddress, 1331);
try {
this.socket.send(packet);
}
catch (IOException e) {
e.printStackTrace();
}
}
public void sendObject(Object object) {
baos = new ByteArrayOutputStream(6400);
oos = null;
try {
oos = new ObjectOutputStream(baos);
oos.writeObject(object);
}
catch (IOException e) {
e.printStackTrace();
}
sendData(baos.toByteArray());
}
}
Code to send the object to server
public class MultiplayerState extends State{
private World world;
private Tank myTank, playerTank;
public MultiplayerState(Handler handler) {
super(handler);
}
#Override
public void startState() {
world = new World(handler,"res/worlds/world1.txt");
handler.setWorld(world);
myTank = new Tank(handler, world.getSpawnX(), world.getSpawnY());
handler.getGame().getRender().addObject(world);
handler.getGame().getRender().addObject(myTank);
world.start();
myTank.start();
handler.getGame().getClient().sendObject(handler.getGame().getPlayer());
}
}
handler.getGame().getClient().sendObject(handler.getGame().getPlayer());
This line to send player to server .. some explanation about code .. this is a game using multithreading in java and i want to create simple network to make two different laptops playing this game online because of that i made this network. I created class Handler this is a class to manage all the game, using object instance of Handler class I can get anything in the game and I want to get object instance of Player class to send it to server because I want to do something to make the game online.
I solved this exception by made GameClient object in Game class transient because I don't want to serialize it. What I want is to use this object to send something to server from Game object internally.
Related
I am trying to process an object on the server with UDP. I serialize it, send it to the server. On the server, I deserialize, modify, then serialize back to send back to the client. On the client I get it, and when I try to readObject () I get an EOF exception. Please help, what could be the problem? I didn't find the answer anywhere.
This is client:
public class Client {
public static void main(String[] args) {
Help help = new Help("WTF");
try {
byte[] objByteArray = serialize(help);
DatagramSocket ds = new DatagramSocket();
InetAddress host = InetAddress.getLocalHost();
int port = 6789;
int objLength = objByteArray.length;
DatagramPacket dp = new DatagramPacket(objByteArray, objLength, host, port);
ds.send(dp);
dp = new DatagramPacket(objByteArray, objLength);
ds.receive(dp);
byte[] new_arr = objByteArray;
Help deserializedObj = (Help) deserialize(objByteArray);
System.out.println(deserializedObj.getData());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (SocketException e) {
throw new RuntimeException(e);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
} catch (IOException e) {
e.printStackTrace();
}
}
public static byte[] serialize(Object obj) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)){
oos.writeObject(obj);
byte[] objByteArray = baos.toByteArray();
return objByteArray;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static Object deserialize(byte[] arr) throws IOException, ClassNotFoundException {
Object result = null;
try (ByteArrayInputStream bais = new ByteArrayInputStream(arr);
ObjectInputStream ois = new ObjectInputStream(bais)){
result = ois.readObject();
}
catch (IOException e){
}
return result;
}
}
And this is Server:
public class Server {
public static void main(String[] args) throws IOException {
String filepath = System.getProperty("user.dir") + "\\src\\Server\\Data\\Collection.json";
CollectionManager.setFilePath(filepath);
byte[] arr = new byte[100000];
DatagramSocket ds = new DatagramSocket(6789);
DatagramPacket dp = new DatagramPacket(arr, arr.length);
ds.receive(dp);
try {
Help deserializedObj = (Help) deserialize(arr);
deserializedObj.setData("Server finished work!");
System.out.println("Done!");
byte[] serializedObj = serialize(deserializedObj);
InetAddress host = dp.getAddress();
int port = dp.getPort();
dp = new DatagramPacket(serializedObj, serializedObj.length, host, port);
ds.send(dp);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
public static byte[] serialize(Object obj) {
try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos)){
oos.writeObject(obj);
byte[] objByteArray = baos.toByteArray();
return objByteArray;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static Object deserialize(byte[] arr) throws IOException, ClassNotFoundException {
Object result = null;
try (ByteArrayInputStream bais = new ByteArrayInputStream(arr);
ObjectInputStream ois = new ObjectInputStream(bais)){
result = ois.readObject();
}
catch (IOException e){
}
return result;
}
}
And also the classes:
public class Help extends Command implements Serializable {
public Help(String name){
super.setName(name);
}
private String data;
public void setData(String s){
data = s;
}
public String getData(){
return data;
}
#Override
public void execute() {
}
}
The problem was that the packet sent from the server is larger than the original one, therefore, on the client, we must receive data into the buffer with a margin, and from there try to read the data.
This is an edited Client code:
byte[] buffer = new byte[1024];
dp = new DatagramPacket(buffer, buffer.length);
ds.receive(dp);
I'm trying to send Message object from Server module to Client module. Unfortunately it throw java.io.StreamCorruptedException: invalid type code: 64 error. Does anyone know what is the problem with code below?
Client class from Server module
private boolean needToRun;
public final Socket socket;
private OutputStream outputStream;
private InputStream inputStream;
private ObjectOutputStream objOut;
private ObjectInputStream objIn;
public Client(Socket socket) {
this.needToRun = true;
this.socket = socket;
try {
this.outputStream = socket.getOutputStream();
this.inputStream = socket.getInputStream();
this.objOut = new ObjectOutputStream(outputStream);
this.objIn = new ObjectInputStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
run();
}
public void send(Message msg) {
try {
objOut.writeObject(msg);
objOut.flush();
objOut.reset();
} catch (Exception ex){
ex.printStackTrace();
}
}
public void close() {
needToRun = false;
}
public void run() {
new Thread(() -> {
while(needToRun) {
try {
int amount = inputStream.available();
if (amount != 0) {
Message msg = (Message) objIn.readObject();
receivedContent(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
public void receivedContent(Message msg) {
for (Client connection : Server.clients) {
connection.send(msg);
}
}
the Client class from Client module looks the same but receivedContent looks like this:
public void receivedContent(Message msg) {
String errorName = msg.content().trim();
MainPane.addLabel(errorName);
}
and last one Server class, which accepts socket connections:
while (true) {
System.out.println("running");
try {
System.out.println("Waiting for client...");
Socket socket = serverSocket.accept();
clients.add(new Client(socket));
} catch (Exception e) {
if (!serverSocket.isClosed()) {
stopServer();
}
break;
}
}
So I have seen a lot of different questions like this but no definitive help, at least to my understanding or my personal application. I am making a socket "chat room" program that allows the user to send images to selected users through a central server. I can establish the clients to connect but when sending an image this error occurs. Here is my code:
Client:
Thread thread = new Thread() {
#Override
public void run() {
try {
s = new Socket("localhost", 4000);
while (s.isConnected()) {
oos = new ObjectOutputStream(s.getOutputStream());
if (!initialized) {
oos.writeObject(identity);
oos.flush();
oos.reset();
initialized = true;
}
baos = new ByteArrayOutputStream(1000);
// Take screenshot
BufferedImage img = new Robot()
.createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize()));
// Write img to baos
ImageIO.write(img, "jpg", baos);
// Send image over socket
oos.writeObject(baos.toByteArray());
oos.flush();
oos.reset();
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
Central Server Home:
public Home() {
initComponents();
textView = new Terminal(terminal);
users = new CopyOnWriteArrayList<>();
Thread startServer = new Thread(new ServerStart());
startServer.start();
}
public class ServerStart implements Runnable {
#Override
public void run() {
try {
serverSock = new ServerSocket(4000);
terminal.append("Server started...\n");
while (true) {
// Detect client connection
Socket clientSock = serverSock.accept();
Thread thread = new Thread(new ClientHandler(clientSock));
thread.start();
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
public class ClientHandler implements Runnable {
Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
#Override
public void run() {
try {
User user = new User(socket);
terminal.append(user.getName() + " connected as " + user.getType() + "...\n");
if (user.getType().equals(User.TYPE_01)) {
users.add(user);
} else {
User client = findUser(user);
while(true){
user.sendScreen(client.receiveScreen());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private User findUser(User user) {
for (User client : users) {
if (client.getCompany().equals(user.getCompany())) {
if (client.getName().equals(user.getName())) {
return client;
}
}
}
return null;
}
}
Central Server User:
public static final String TYPE_00 = "VIEWER";
public static final String TYPE_01 = "CLIENT";
private byte[] bytes;
private ObjectInputStream in;
private ObjectOutputStream out;
private String company, name, type;
public User(Socket socket) throws IOException {
this.out = new ObjectOutputStream(socket.getOutputStream());
this.in = new ObjectInputStream(socket.getInputStream());
setUserType();
}
public void sendScreen(byte[] bytes) {
try {
out.writeObject(bytes);
out.flush();
} catch (Exception ex) {
ex.printStackTrace();
}
}
public byte[] receiveScreen() {
byte[] bytes = null;
try {
bytes = (byte[]) in.readObject();
} catch (Exception e) {
e.printStackTrace();
}
return bytes;
}
public String getCompany() {
return company;
}
public String getName() {
return name;
}
public String getType() {
return type;
}
public void setUserType()
{
String[] strings = null;
try{
strings = (String[])in.readObject();
type = strings[0];
company = strings[1];
name = strings[2];
} catch(Exception e){
e.printStackTrace();
}
}
Client Viewer:
Thread thread = new Thread() {
#Override
public void run() {
try {
Socket s = new Socket("localhost",4000);
String[] strings = { TYPE, "Vision", "cadams" };
while (s.isConnected()) {
if(!initialized){
System.out.println("initialized");
oos = new ObjectOutputStream(s.getOutputStream());
oos.writeObject(strings);
oos.flush();
oos.reset();
initialized = true;
}
ois = new ObjectInputStream(s.getInputStream());
byte[] bytes = (byte[]) ois.readObject();
BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
ImageIcon ico = new ImageIcon(
img.getScaledInstance(viewer.getWidth(), viewer.getHeight(), Image.SCALE_SMOOTH));
viewer.setIcon(ico);
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
thread.start();
}
I have done some extensive research and know that this could be from my streams looking like a bowl of ramen noodles but I haven't seen any sort of proposal on how to fix it in terms of source. I thank those who can contribute and please let me know if there is anything I can do to further understanding.
Don't keep creating new ObjectInput/OutputStreams. Use the same ones for the life of the socket.
NB while (s.isConnected() isn't valid. It doesn't magically become false when the peer disconnects. You need to handle end of stream and the various socket termination exceptions.
I am new to java client server communications and I'm confronted with sending an object from client side to server side. Somehow my programm stucks while trying to transfer an object. The likely reason might be the ObjectOutputStream implementation.
Database login button
class Handler implements ActionListener {
Client client = new Client();
List<String> parameterList = new ArrayList<String>();
ClientParameter parameter;
public void actionPerformed(ActionEvent event) {
if(event.getSource()==buttonConnect) {
parameterList.add(username);
parameterList.add(password);
parameter = new ClientParameter(parameterList);
client.connectToServer(parameter);
}
Object ClientParameter
public class ClientParameter {
List<String> parameterList;
public ClientParameter(List<String> parameterList) {
this.parameterList = parameterList;
}
public List<String> getParameterList() {
return parameterList;
}
public void setParameterList(List<String> parameterList) {
this.parameterList = parameterList;
}
}
Class client
public void connectToServer(ClientParameter parameter) {
// Verbindung mit dem Server herstellen
Socket server = null;
try {
server = new Socket("localhost", 3141);
// programm hangs while reading this 2 lines..
ObjectInputStream objectIn = new ObjectInputStream(server.getInputStream());
ObjectOutputStream objectOut = new ObjectOutputStream(server.getOutputStream());
objectOut.writeObject(parameter);
} catch(UnknownHostException e) {
e.printStackTrace();
} catch(IOException e) {
e.printStackTrace();
} finally {
if(server!=null) {
try {
server.close();
} catch(IOException e) {
System.out.println(e);
}
}
}
}
And the server class
public class Server {
private static void handleConnection(Socket client) throws IOException {
ObjectInputStream objectIn = new ObjectInputStream(client.getInputStream());
ObjectOutputStream objectOut = new ObjectOutputStream(client.getOutputStream());
ClientParameter parameter;
try {
parameter = (ClientParameter) objectIn.readObject();
System.out.println(parameter);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws IOException {
ServerSocket server = new ServerSocket(3141);
while(true) {
Socket client = null;
try {
client = server.accept();
handleConnection(client);
}
catch(IOException e) {
e.printStackTrace();
}
finally {
if(client!=null) {
try {
client.close();
}
catch(IOException e) {
System.out.println(e);
}
}
}
}
}
}
Thank you!
The server starts by reading what the client sends. And the client also starts by reading what the server sends. So it's a deadlock.
Indeed, as documented, the constructor of ObjectInputStream blocks until it has received the serialization stream header:
A serialization stream header is read from the stream and verified. This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.
Remove the following line, since you don't do anything with the ObjectInputStream anyway:
ObjectInputStream objectIn = new ObjectInputStream(server.getInputStream());
I recently started learning networking with sockets in java. So i've created a multiplayer game that is playable on the same computer but i wanted to make it network-multiplayer, then i learned about sockets, now, i want to send the variables of the position of the player in the game to a server which then can place that player in that position in the other game instance running on a different machine. And the thing is, i just fail at it and all the data doesnt get received or read. I also want the position to get sent and received constantly which is also a problem for me...
I tried using ObjectOutputStream and ObjectInputStream to send a int array with the variables but that also failed, so could you please show me how to do this, because i have no idea and i cant seem to find an answer online.
Thx
As the easiest solution, use the Object Streams to send an object created by you where you store these coordinates, but this class must implement Serializable interface. For example for 2d coordinates:
class Coords implements Serializable {
int x, y;
public Coords(int x, int y) {
this.x = x;
this.y = y;
}
}
...
// To write:
// oos = ObjectOutputStream of the socket
Coords tmp = new Coords(x, y);
oos.writeObject(tmp);
oos.flush();
...
//To read:
//ois = ObjectInputStream of the socket
Coords tmp = (Coords)ois.readObject();
http://java.sun.com/developer/technicalArticles/ALT/sockets/ can also aid you.
try something like this:
import java.io.*;
import java.net.*;
class Server extends Thread {
Server() throws IOException {
serverSocket = new ServerSocket(0);
}
public void run() {
while (true) {
try {
Socket client = serverSocket.accept();
Connect c = new Connect(client);
c.start();
} catch (Exception e) {}
}
}
final ServerSocket serverSocket;
}
class Data implements Serializable {
int[] data = { 1, 2, 3 };
}
class Connect extends Thread {
public Connect(Socket clientSocket) {
client = clientSocket;
try {
ois = new ObjectInputStream(client.getInputStream());
oos = new ObjectOutputStream(client.getOutputStream());
} catch (Exception e1) {
try {
client.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
return;
}
}
public void run() {
try {
oos.writeObject(new Data());
oos.flush();
ois.close();
oos.close();
client.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
System.out.println("done");
}
final Socket client;
ObjectInputStream ois;
ObjectOutputStream oos;
}
class Client {
Client(int port) {
this.port = port;
}
void connectAndRead() {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
Socket socket = null;
Data data = null;
try {
socket = new Socket("127.0.0.1", port);
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
data = (Data) ois.readObject();
oos.close();
ois.close();
for (int d : data.data)
System.out.println(d);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
final int port;
}
public class Main {
public static void main(String[] arguments) throws IOException, InterruptedException {
Server server = new Server();
server.start();
Client client = new Client(server.serverSocket.getLocalPort());
client.connectAndRead();
}
}