java.io.StreamCorruptedException: invalid stream header: 74001057 - java

I'm now creating a simple TicTacToe game on Android phone.
I used java server to handle multiplayer part, but when I pair the players and 'new' the ObjectInputStream, it throw me the exception.
java.io.StreamCorruptedException: invalid stream header: 74001057
These is my server code when create a new game thread:
public GameThread(Socket Player1, Socket Player2) {
this.Player1 = Player1;
this.Player2 = Player2;
System.out.println("GameThread Started!");
//Exception throw at the codes below
new ReceiveMessagesThread(this.Player1, this.Player2).start();
new ReceiveMessagesThread(this.Player2, this.Player1).start();
}
These is my server codes for receiving message in a game thread:
// This is an inner class.
private class ReceiveMessagesThread extends Thread {
private Socket SourceClient, DestinationClient;
ReceiveMessagesThread(Socket SourceClient, Socket DestinationClient) {
this.SourceClient = SourceClient;
this.DestinationClient = DestinationClient;
}
#Override
public void run() {
while (true) {
try {
// Exception throw at the line below
ObjectInputStream in = new ObjectInputStream(this.SourceClient.getInputStream());
switch (in.readByte()) {
case ServerGlobal.BOARD_STATUS:
GameBoard = (char[][]) in.readObject();
SendBoardStatus(this.DestinationClient);
break;
}
}
catch (java.io.StreamCorruptedException ex) {
ex.printStackTrace();
break;
}
catch (IOException | ClassNotFoundException ex) {
Logger.getLogger(GameThread.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}

Move the creation of the ObjectInputStream ahead of the loop. It tries to read a stream header placed there by the peer's ObjectInputStream, which you should likewise only create once. These streams should persist for the life of the socket, not be created anew for each send or receive.

If you output the array of chars into ObjectOutputStream by separate chars, then you should read it also by chars, not as an array.
Also, check for consistent usage of ObjectOutputStream and ObjectInputStream. In your code on github you use DataInputStream in some places.
Also ensure that every wrapping of socket.getInputStream() with new ObjectInputStream() matches corresponding unwrapping of socket.getOutputStream() with new ObjectOutputStream(). Or better yet, wrap the socket streams in ObjectInputStream and ObjectOutputStream only once, not every time you want to read/write something.

Related

How can i keep a stream opened to receive data without closing the socket and waiting for client's data?

I'm programming in Java and i'm making a socket connection between server and several clients (using threads).
In the client side i made an opened Socket that connects to the server in a respective port and i send several objects, then the client disconnects.
In the server side i made a ServerSocket (where the client connects) and i use the accept() method to get the Socket, i don't want the socket to close so i keep it opened until i want (using a method for example), then i create an stream (ObjectInputStream) and read every object sent from the client, but i don't want it to close too. To continue the understanding of my problem here is the class i made:
import java.io.*;
import java.net.*;
public class ServerConnection implements Runnable{
private Socket connection;
public ServerConnection(Socket c){
connection = c;
}
#Override
public void run() {
// I used String i this example, but the real code use a Object sending system that i created
// because i needed to send different objects in one object (this ones implements Serializable).
String msg;
try {
ObjectInputStream inStream = new ObjectInputStream(connection.getInputStream());
do{
inStream.
msg = ((String)inStream.readObject());
System.out.println(msg);
}
while(!msg.equals("FINISH CONNECTION"));
} catch (IOException ex) {
System.err.println("run() - (io): "+ex.getMessage());
try {
connection.close();
} catch (IOException ex1) {
System.err.println("run() - (io/io): "+ex.getMessage());
}
} catch (ClassNotFoundException ex) {
System.err.println("run() - (classNF): "+ex.getMessage());
}
}
// The main method was created to make tests
// I'll use objects of this class to every client connection
public static void main(String[] args){
try {
ServerSocket server = new ServerSocket(8010);
Socket connection = server.accept();
ServerConnection svConnection = new ServerConnection(connection);
Thread theThread = new Thread(svConnection);
theThread .start();
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
}
This can receive the Strings i sent from the client, but the do-while isn't able to catch exceptions, the IOException is throwed when the Stream has no more Strings, so i want to prevent the throwing of that exception when the stream doesn't have more Strings to read, i tried to use recursive try-catch but i know that is not recommended. So there is another solution to this?
(Every answer is welcome. Thanks)
(EDIT)
For those one who needs the client code, so here it is:
import java.io.*;
import java.net.*;
public class ClientConnnection{
// There is a method that i don't make yet
public static void main(String[] args){
try {
Socket socketToServer = new Socket("localhost",8010);
ObjectOutputStream outStream = new ObjectOutputStream(socketToServer.getOutputStream());
outStream.writeObject(new Message("Hello :D"));
outStream.writeObject(new Message("How r u?"));
outStream.writeObject(new Message("Other message"));
outStream.flush();
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}

Java : ObjectInputStream, 3 messages sent, only 2 received

Welcome to the fabulous world of networks. I discovered my passion. :)
However I have a very strange behavior in my app, and I would need your help to solve this one.
I made a simple server-client app.
The sending Thread :
new Thread(new Runnable() {
public void run() {
try {
ObjectOutputStream objectOutputStream = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
objectOutputStream.writeObject(message);
objectOutputStream.flush();
} catch (Exception exception) {
exception.printStackTrace();
}
}
}).start();
The receiving Thread :
new Thread(new Runnable() {
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
Message message = (Message) objectInputStream.readObject();
Log.i("DEBUG", message);
}
} catch (Exception exception) {
try {
socket.close();
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
}).start();
It works just fine, however if I send simultaneously 3 messages, my receiving thread only receives the 2 first ones. It does not matter if I change the order. The third is always lost.
I think it's a buffer size problem. How can I deal with that? Thank you. :)
BufferedReader buffers the input, just as the name says. This means that it reads from the input source into a buffer before passing it onto you. The buffer size here refers to the number of bytes it buffers.
ObjectInputStream objectInputStream = new ObjectInputStream(new BufferedInputStream(socket.getInputStream(), size));
you can use size of BufferedInputStream and the reading of the buffer is slow so send the data with some delay
`

Handling multiple threads in a Client-Server architecture for File synchronization

I had to implement a Client-Server application in Java that automatically updates txt files in a Server directory depending on changes in the files in the Client side, for a homework assignment (had to, because I'm past the deadline).
I have a package that handles the changes in the files correctly, but I'm stumped about how to handle the changes in multiple files. My approach was using separate threads for each file in the client directory and using corresponding threads in the server directory for the same cause. This approach works for a single file, but not for multiples.
The code below is on the client side and calls a file's thread's checkfilestate method to handle the updates.
while(true){
for (Map.Entry<String, SynchronisedFile> entry : fileList.entrySet()) {
try {
System.err.println("SyncTest: calling fromFile.CheckFileState()");
sstt.start();
entry.getValue().CheckFileState();
} catch (IOException e) {
e.printStackTrace();
System.exit(-1);
} catch (InterruptedException e) {
e.printStackTrace();
System.exit(-1);
}
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
System.exit(-1);
}
}
And on the server side, if I start a single thread using:
Thread sstt = new Thread(new SyncThreadServer(sfileList.entrySet().iterator().next().getValue(),clientSocket));
sstt.start();
It works as expected. But if I start the serverside threads at the same time (which contains methods for decoding the Json messages from the input stream) using:
for (Map.Entry<String, SynchronisedFile> entry : sfileList.entrySet())
{
Thread sstt = new Thread(new SyncThreadServer(entry.getValue(),clientSocket));
sstt.setName(entry.getKey());
}
Threads of other files start reading JSON messages intended for other threads from the input stream. I'd like to be able to stop the serverside loop from starting the next thread, at least until the checkFile method is complete for one file/thread. But I still might run into problems after the initial stage, when all the treads are running at the same time. Any solutions on how to handle multiple threads in this case? (All threads use a single socket).
Edit: As I understand, this has to do with synchronization. Threads of other files on the server are accessing the Input stream before the first thread has even finished processing the inputs meant for it. This is the code of the server thread below. I need to somehow block the other threads from accessing the input stream before the first one has finished using it. Any help would be much appreciated. Thanks.
public class SyncThreadServer implements Runnable {
SynchronisedFile toFile; // this would be on the Server //Is an instance of the syncfile class, should be able to proc insts
Socket clientSocket;
public SyncThreadServer(SynchronisedFile tf, Socket aClientSocket){
toFile=tf;
clientSocket = aClientSocket;
}
#Override
public void run() {
Instruction inst = null;
InstructionFactory instFact=new InstructionFactory();
while(true){
{
try{
DataInputStream in = new DataInputStream(clientSocket.getInputStream());
DataOutputStream out = new DataOutputStream(clientSocket.getOutputStream());
String smsg = in.readUTF();
Instruction receivedInst = instFact.FromJSON(smsg);
System.err.println(smsg);
// The Server processes the instruction
toFile.ProcessInstruction(receivedInst);
//if(receivedInst.Type().equals("EndUpdate")){
// out.writeUTF("NEXT"); //TODO: Change to Json
// out.flush();}
//else
//{
out.writeUTF("GO"); //TODO: Change to Json
out.flush();
}
//}
catch (IOException e) {
e.printStackTrace();
System.exit(-1); // just die at the first sign of trouble
} catch (BlockUnavailableException e) {
// The server does not have the bytes referred to by the block hash.
try {
DataOutputStream out2 = new DataOutputStream(clientSocket.getOutputStream());
DataInputStream in2 = new DataInputStream(clientSocket.getInputStream());
out2.writeUTF("NGO"); //TODO: Change to Json
out2.flush();
String msg2 = in2.readUTF();
Instruction receivedInst2 = instFact.FromJSON(msg2);
toFile.ProcessInstruction(receivedInst2);
if(receivedInst2.Type().equals("EndUpdate")){
out2.writeUTF("NEXT"); //TODO: Change to Json
out2.flush();}
else
{
out2.writeUTF("GO"); //TODO: Change to Json
out2.flush();
}
} catch (IOException e1) {
e1.printStackTrace();
System.exit(-1);
} catch (BlockUnavailableException e1) {
assert(false); // a NewBlockInstruction can never throw this exception
}
}
// } //And here
}
}
}

Java ObjectInputStream(socket.getInputStream()) catches null object

I'm making a client server couple. My client connects to server very well and it creates ObjectInputStream(socket.getInputStream()) over the socket, from server to client and vice versa. Then for some mystical reason my ObjectInputStream of the server somehow catches a null object. Client haven't sent anything over the socket (I did put /../ over the object send method to make this sure and even System.out.printed all the objects sent earlier) Server catches that mystical object only once, and after that all the objects sent By client work just as they should..
class ClientThread extends Thread {
//The socket where to listen/talk
Socket socket;
ObjectInputStream sInput;
ObjectOutputStream sOutput;
InputStream fInput;
OutputStream Output;
//my unique id (easier for deconnection)
int id;
//Objects that we will be receiving
Incomingdata datain;
//the date we connect
String date;
Player player;
boolean Connected = false;
//Constructor
ClientThread(Socket socket){
id = uniqueId++;
this.socket = socket;
try{
sOutput = new ObjectOutputStream(socket.getOutputStream());
sInput = new ObjectInputStream(socket.getInputStream());
Output = socket.getOutputStream();
} catch (Exception e){
System.out.println("Couldn't create Input/Output streams");
}
date = new Date().toString();
}
// what will run forever
public void run() {
// to loop until LOGOUT
Connected = true;
while(Connected) {
try {
datain = (Incomingdata) sInput.readObject(); //<--- this catches the mystical null! Even if nothing is sent over the socket?
}
catch (IOException e) {
TextArea.AddLine("Exception reading Streams: " + e);
break;
}
catch(ClassNotFoundException e2) {
break;
}
You can only receive a null if you send a null.
(There is a widespread misconception that readObject() returns null at end of stream. It doesn't.)

readObject method only reads the first object it receives

Just to give the background of my issue; I'm writing a client server application. when a client initially connects, the server accesses the database and send all the items in a particular table to the client by writing the objects to an objectoutputstream in a for loop.
The issue is, the client reads only the first object that is being sent. Even if I create a new object and send it to the server for verification the client does not pick it up when the server sends it back after inserting to database... extract from code:
Server:
public void loadClients()
{
ArrayList <Client> list = dBCon.loadClients();
try
{
for (int i =0; i<list.size();i++)
{
sendtoClient(list.get(i));
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void sendtoClient(Object obj) throws IOException
{
_out.writeObject(obj);
_out.flush();
_out.reset();
}
Client:
socket = new Socket("localhost", 4447);
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
Object objIn = ois.readObject();
Client client = (Client)objIn;
switch(client.actionType)
{
case ("ADD"):
{
if(clientFrame.tbDeals!=null)
{
clientFrame.tbDeals.addClient(client);
break;
}
else
{
clientList.add(client);
System.out.println(client.clientName);
break;
}
}
}
Edit: I have tried with a while loop on the client side as well. then ois.available() returns 0....
You're reading exactly one object on the client side. That's all you're going to get.
available() is rarely if ever used when doing basic IO in Java, and generally isn't going to do what you think it does.
Reading from a ObjectInputStream is blocking, just like all other basic Java IO. Using readObject() you will either get an object, or an exception as noted in the javadoc
The most simplistic example of how you would handle this in a loop if you have no idea the number of objects you'll be receiving and expect the connection to stay open is:
while (true) {
try {
Object o = ois.readObject();
/// do something with the object you just read
} catch ( EOFException e) {
System.out.println("remote connection closed!");
e.printStackTrace();
break;
}
}

Categories