Socket programming, multithreaded game, getting an End Of File Exception - java

I'm trying to implement a little game, where multiple clients have to connect to a server, and play together. Every one has a different GUI and they communicate through the class ClientConnect, which is a Runnable started from the GUI class. The problem is that i'm getting an EOFException at the first lines of code, when i'm trying to intanciate the inputstream. The server is of course started at the beginning and sending an object.
Here is a cut of the implementation where i get the exception.
What should i do?
public ClientConnect(InetAddress address, int port) throws IOException {
clientSock = new Socket(address, port);
}
#Override
public void run() {
ArrayList<Object> receivedObject = null;
try (ObjectInputStream fromServer = new ObjectInputStream(clientSock.getInputStream());
ObjectOutputStream toServer = new ObjectOutputStream(clientSock.getOutputStream()))
{
while(!move) {
receivedObject = (ArrayList<Object>) fromServer.readObject();
move = !(receivedObject.get(0).equals("you have to wait!!"));
}
actualPlayer = (String) receivedObject.get(0);
scoreCard = (List<String>) receivedObject.get(1);
highScore = (HashMap<String, Integer>) receivedObject.get(2);
numberOfPlayers = (int) receivedObject.get(3);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Here is the exception:
CShellExt::CShelljava.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at edu.hm.se2.kniffel.ClientConnect.run(ClientConnect.java:41)
at java.lang.Thread.run(Unknown Source)
Ext()
The line 41 is the line with the try
I'm starting the ClientConnect thread in the GUI like that:
public void actionPerformed(ActionEvent arg0) {
//Online-Spiel starten
if(game.listLength()>0){
try {
client = new ClientConnect(InetAddress.getByName(null), 2000);
new Thread(client).start();
while (!client.getMove()) {
lblActualUser.setText("WAITING.... " + client.getActualPlayer() + " ist an der Reihe");
}

Got it!
I Got something blocking the serversocket to be opened!

On this evidence, the peer isn't creating an ObjectOutputStream at all, it's just connecting and then closing the socket.
You should construct the ObjectOutputStream before the ObjectInputStream, at both ends.

Related

Starting Threads without Stopping them in my Server Socket causes disconnections

I have a server coded with Java using Eclipse, I am running Android Apps on this server
my two phones and the server are at the same network .
when I connect from the phones two the server I can see the clients connect to the server
and when a client is disconnected I can see that too.
when I connect from the first client then I make a connection from the second client then the first client automatically disconnect for no reason.
which means I can not make two moves on the server without one of the client disconnect.
maybe the thing is that when a client connect to the server a thread is created (myThread) but when the client is disconnected I think the thread (MyThread) is never stopped.
I can see that I get to 30 Thread names.
my question is , if the many threads cause the disconnection, how to stop every thread after the client is diconnected?
public Server() {
// ServerSocket is only opened once !!!
try {
serverSocket = new ServerSocket(6000);
System.out.println("Waiting on port 6000...");
boolean connected = true;
// this method will block until a client will call me
while (connected) {
Socket singleClient = serverSocket.accept();
// add to the list
ServerThread myThread = new ServerThread(singleClient);
allClients.add(myThread);
myThread.start();
}
// here we also close the main server socket
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class ServerThread extends Thread {
Socket threadSocket;
String userName;
boolean isClientConnected;
InputStream input;
ObjectInputStream ois;
OutputStream output;
ObjectOutputStream oos;
public ServerThread(Socket s) {
threadSocket = s;
}
public void sendText(String text) {
try {
oos.writeObject(text);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run() {
try {
counter++;
input = threadSocket.getInputStream();
ois = new ObjectInputStream(input);
output = threadSocket.getOutputStream();
oos = new ObjectOutputStream(output);
userName = (String) ois.readObject();
isClientConnected = true;
while (isClientConnected) {
String singleText;
singleText = (String) ois.readObject();
oos.flush();
for (ServerThread t : allClients)
if (t.isAlive())
t.sendText(singleText);
}
// close all resources (streams and sockets)
ois.close();
oos.close();
threadSocket.close();
counter--;
System.out
.println("disconnected : lost connection - connections: "
+ counter);
} catch (Exception e) {
// TODO Auto-generated catch block
counter--;
isClientConnected = false;
System.out.println("Quit App : lost connection - connections: "
+ counter);
}
}
}
i figured it out before, i just removed the userName = (String) ois.readObject(); before the loop and it worked fine .. tHANK YOU ALL
– amjad

Java:Android - Server socket EOFException with Objectstream

I'm rather new to server sockets, trying to learn how to code a socket (ive had past experience with using sockets like winsock but this is my first time actually coding one in java).
This is the error I keep getting:
Couldn't get I/O for the connection to: 0
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
This is the code:
public static void main(String args[]) {
ServerSocket MyService = null;
Socket clientSocket = null;
Integer clientNum = 0;
Integer inputID, outputID;
try {
MyService = new ServerSocket(hidden);
} catch (IOException e) {
e.printStackTrace();
}
try {
clientSocket = MyService.accept();
ObjectInputStream input = new ObjectInputStream(clientSocket.getInputStream());
ObjectOutputStream output = new ObjectOutputStream(clientSocket.getOutputStream());
Float inputFloat = null;
Float outputFloat = null;
Protocol protocol = new Protocol();
outputFloat = protocol.processFloatInput(null);
while(true) {
if(input.readObject().getClass().equals(inputFloat.getClass())) {
System.out.println("true");
if ((inputFloat = input.readFloat()) != null) {
outputFloat = protocol.processFloatInput(inputFloat);
output.writeObject(outputFloat);
System.out.println("Float value = " + inputFloat);
}
input.close();
output.flush();
output.close();
}
if(input.readObject().getClass().equals(Integer.TYPE)) {
if ((inputID = input.readInt()) != null) {
outputID = protocol.processIntegerInput(inputID);
output.writeObject(inputID);
System.out.println("Client " + outputID + " connected.");
}
input.close();
output.flush();
output.close();
}
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host: hostname");
} catch (IOException e) {
//Error printed
System.err.println("Couldn't get I/O for the connection to: " + clientNum);
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
};
In past tests, i was able to connect to the server, but since I want to check the input data type before operating, I get this.
Thanks for the help :)
EOFException just means you got to the end of the stream. It's normal.
Your problem is that you're reading twice for every object written: once to get its class and again to get the object. You don't get the same object again, you get the next object, so you run out eventually.
You need to store the result of readObject() in a variable, then test its class, then cast it appropriately.

EOFException after calling socket.shutdownOutput()

like the headline says I´m getting an EOFException on the serverside after i called shutdownOutput() at the clientside
this is at the serverside:
public void getRestaurant() {
String tempRestaurant=null;
try { BufferedReader fr =
new BufferedReader( new FileReader( "Restaurant.txt" ));
tempRestaurant = fr.readLine();
System.out.println( tempRestaurant );
System.out.println("writing tempRestaurant is the next Step");
oos.writeObject(tempRestaurant);
System.out.println("tempRestaurant has been written");
oos.close();
fr.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
and this is the code at the clientside:
protected String doInBackground(Void... params) {
connecttoServer();
System.out.println("connecting to server...");
try {
oos.writeInt(1);
System.out.println("next step is closing");
serverside.shutdownOutput();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
System.out.println("connected to server");
Restaurant=(String) ois.readObject();
System.out.println("doInBackground(): "+Restaurant);
and this is the error code:
java.io.EOFException
at java.io.DataInputStream.readInt(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readInt(Unknown Source)
at java.io.ObjectInputStream.readInt(Unknown Source)
at prealphaserverpackage.clientsidethreads.handlerequest(Serverpart.java:355)
at prealphaserverpackage.clientsidethreads.run(Serverpart.java:156)
pls comment if you need any further informations i will put them online as soon as possible :)
I forgot to call oos.flush(); While the server was still waiting for the data, I closed the stream. That was the reason for the EOFException.

Connection reset, java

I am getting a lot of connection reset errors, trough debugging i found out that the code is found within these lines:
//set up output stream for objects
output = new ObjectOutputStream(socket.getOutputStream());
output.flush(); //flush the output buffer to send header information
// Read a message sent by client application
ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
The error occurs at this line:
String message = (String) ois.readObject();
The error message:
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peek(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at org.bitbucket.c4d3r.ConnectionListener.listen(ConnectionListener.java:47)
at org.bitbucket.c4d3r.ConnectionListener.<init>(ConnectionListener.java:27)
at org.bitbucket.c4d3r.ConnectionHandler.connectionServer(ConnectionHandler.java:46)
at org.bitbucket.c4d3r.ConnectionHandler.run(ConnectionHandler.java:24)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
I know that the connection reset is caused by a socket that's closed unexpectedly, however i am quite new to sockets and i am unable to find what i am doing wrong. Therefore i was hoping that someone could help me out with this. For a better vision of everything i have copied a bigger block of code beneath
private DomainController dc;
private Socket socket;
private boolean changed;
private ObjectOutputStream output;
private ObjectInputStream ois;
private Map json;
public ConnectionListener(DomainController dc, Socket socket) {
this.dc = dc;
this.socket = socket;
listen();
}
#Override
public void run() {
listen();
return;
}
#SuppressWarnings("finally")
public void listen() {
try
{
//set up output stream for objects
output = new ObjectOutputStream(socket.getOutputStream());
output.flush(); //flush the output buffer to send header information
// Read a message sent by client application
ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
boolean inProgress;
//CHECK IF THERE ARE GIVEN COMMANDS
if(message.substring(0, 8).equalsIgnoreCase("COMMAND="))
{
switch(message.substring(8))
{
case "askMinigames":
//System.out.println("Sending minigames list");
output.writeObject(new String(dc.getProp().getProperty("minigames")));
output.flush(); //flush output to client
break;
}
}
} catch (SocketException ex) {
System.out.printf("Connection reset\n");
ex.printStackTrace();
} catch (IOException e) {
System.out.println("Input exception");
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
try
{
if(ois != null) {
ois.close();
}
if(output != null) {
output.close();
}
if(socket != null) {
socket.close();
}
}
catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
}
You need to use the same object input and output streams for the life of the socket, at both ends. As you are just sending strings, I don't really see why you're using object streams at all: you could use e.g. DataOutputStream.writeUTF() and DataInputStream.readUTF().

Exception with ObjectInputStream

I have three classes, the client, the server and the handler (which is going to handle the server connections) as I show below:
// The Client
public void sendSomePackage() {
try {
socket = new Socket("localhost", 54321);
sos = socket.getOutputStream();
oos = new ObjectOutputStream(sockOutput);
} catch (IOException e) {
e.printStackTrace(System.err);
return;
}
// About to start reading/writing to/from socket
try {
Package package = new Package(100);
oos.writeObject(pacote);
} catch (IOException e) {
e.printStackTrace(System.err);
}
try {
Thread.sleep(50);
} catch (Exception e) {
e.printStackTrace();
}
// Done reading/writing to/from socket, closing socket.
try {
sock.close();
} catch (IOException e) {
System.err.println("Exception closing socket.");
e.printStackTrace(System.err);
}
//Exiting
}
Now the server class:
// The Server - with a method that just wait for connections
public void waitForConnections() {
while (true) {
try {
socket = serverSocket.accept();
// Server:Accepted new socket, creating new handler for it
SimpleHandler handler = new SimpleHandler(socket);
handler.start();
// Server:Finished with socket, waiting for next connection
}
catch (IOException e){
e.printStackTrace(System.err);
}
}
}
My handler, which just handle the server connections:
#Override
public void run() {
//Handler: Handler run() starting
while (true) {
try {
package = (Package) ois.readObject();
if (pacote != null) {
System.out.println("Package received " + pacote.getSourceid());
}
} catch (Exception e) {
e.printStackTrace(System.err);
break;
}
}
try {
// SimpleHandler:Closing socket
sock.close();
ois.close();
} catch (Exception e) {
// Handler: Exception while closing socket, e=" + e);
e.printStackTrace(System.err);
}
}
The idea is the client send some 'package' object to my server which is going to keep running receiving the 'package' object any time.
The connection works fine, but in the end of the program an exception is launched, this is the one:
Package received 100
java.io.EOFException
at java.io.ObjectInputStream$BlockDataInputStream.peekByte(Unknown Source)
at java.io.ObjectInputStream.readObject0(Unknown Source)
at java.io.ObjectInputStream.readObject(Unknown Source)
at br.ufscar.socket.SimpleHandler.run(SimpleHandler.java:45)
at java.lang.Thread.run(Unknown Source)
I already search for something on Google but nothing so far.
Any idea ?
This is working exactly as you want it to (probably). It reads the 100 then goes through the loop again (while(true) never stops looping until a break statement) and throws an exception because no more data has been sent and it goes to the catch statement and prints the error before exiting your while loop.
EOFException ist an IOException that indicates the end of an stream.
Here we say that if there aren't any more bytes to read then we should break out of the while loop before trying to read the object, etc.
while (true) {
if (ois.read() == -1) break;
//...rest of the code
}
Ok, this is how object streams work and the solution that works everywhere.
Object stream data is preceded by a 4 byte 'magical' sequence AC ED 00 05. An ObjectInputStream will peek for this data at construction time rather than before the first read. And that's logical: one wants to be sure it is a proper stream before being too far in an application. The sequence is buffered by the ObjectOutputStream at construction time so that it is pushed on the stream at the first write.
This method gives rise to complexities in buffered situations or transferring via sockets.
Fortunately there is a just as simple as effective solution to all these problems:
Flush the ObjectOutputStream immediately after construction!
ObjectOutputStream myStream = new ObjectOutputStream ( anotherStream );
myStream.flush();

Categories