I have a server and client applications.
The client and server are in the same machine.
The client and server are using same java version.
I'm using ObjectOutputstream /objectInputStream to write and read
the objects
The transmitted object is notbeing modified while writing
the code :
mySocketClient.getOos().writeObject((replyobject));
mySocketClient.getOos().flush();
mySocketClient.getOos().reset();
Reading Code :
objectInputStream.readObject();
The application is working good but randomly I have the below exception
java.io.StreamCorruptedException: unexpected end of block data
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
What might be causing this?
Related
I'm trying to create application that will send object through local network using Sockets. When i run server and client code in Intellij Idea they work fine, but when i run server code on one pc and client code on another pc i get errors like java.io.StreamCorruptedException: invalid type code: 00 or java.io.StreamCorruptedException: invalid stream header: 6C69656E
byte[] readBuffer = new byte[4096];
int num = inStream.read(readBuffer); //inStream is socket input stream
ByteArrayInputStream bis = new ByteArrayInputStream(readBuffer);
ObjectInput in = new ObjectInputStream(bis);
Object o = in.readObject(); //this line throws error
The thing is that writing and reading object to socket stream works on server (which is on pc where i created project) but reading from input stream on client (another pc where i copied project) throws error.
Can someone help me with this? I searched everywhere for solution but i can't figure out what is problem with serializing, because it works on same pc but won't on another. Is there any way that i can make this pc independent? This also happens when i create jar files and run it on same pc where it works in Intellij Idea.
It can because that client didnt read message fully.
But the real mistake is that you work with TCP socket like a message protocol transport but TCP is a stream protocol so you have to create your own message protocol on top of TCP.
Why it works fine on local system?
Because transport data between client and server happen too fast in local test and maybe in just one frame so all the message transported in just one IO-call but in internet or a network it doesn't work like you think.
There is 2 way to handle this mistake:
1- Pass SocketInputStream directly to ObjectInputStream instance and let it handle read objects.
2- Create a message protocol for example you can put the size of message in 2 or more first bytes. Then you can workd like this :
Read 2(or more) first bytes and detect size of packet.
Create a buffer for this size and read packet bytes.(make sure you read all of packet data from socket . You can use return value of SocketInputStream.read(byte[]) method to calculate it)
Pass the packet to ObjectInputStream and read object !
currently I am working on a school Project. The goal of this project is to receive data from a Server and writing data to the Server. For this purpose I am using Sockets and ServerSockets. To encrypt the messages I am using Apache Commons Codec 1.9.
(Server is a java .jar file executed on an Ubuntu Server and the client is an android app)
Server/Client
To encrypt the messages I am exchanging public keys.
private void Schluesselaustausch() {
try {
GenerateKeys gk = new GenerateKeys(4069);
gk.createKeys();
ServerPrivateKey = gk.getPrivateKey();
ObjectOutputStream oos = new ObjectOutputStream(clientSocket.getOutputStream());
oos.writeObject(gk.getPublicKey());
oos.flush();
ObjectInputStream ois = new ObjectInputStream(clientSocket.getInputStream());
Object obj = ois.readObject();
ClientPublicKey = (PublicKey) obj; //Line 108
} catch (Exception e) {
e.printStackTrace();
}
}
The error occurs when an object is casted to an PublicKey (Line 108).
The Client has the same function, but he is receiving and then sending an object.
The Error
java.lang.ClassNotFoundException: com.android.org.conscrypt.OpenSSLRSAPublicKey
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:582)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:190)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499)
at java.base/java.lang.Class.forName0(Native Method)
at java.base/java.lang.Class.forName(Class.java:374)
at java.base/java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:685)
at java.base/java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1879)
at java.base/java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1765)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2053)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1587)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:422)
at Engine.ClientVerbindung.Schluesselaustausch(ClientVerbindung.java:108)
at Engine.ClientVerbindung.run(ClientVerbindung.java:49)
There is more
Now to the strange part: Everything works if I am using a client running on PC. So I figured out that my server was coded on Java 10 but on my Ubuntu Server there was Java 11 installed. I downgraded Java and tested it again. Nothing changed.
My Questions
Is there an error in Android?
Do I have to upgrade java to 11?
What is the problem?
Thank you for your help.
RT
You are not sending a key (some string or number value) but the whole Java object back and forth through the Object*Streams. When you use a PC you are basically using the same Java implementation as the server, so the server can deserialize this Java object. If you System.out.println the .getClass() of the received object on the server, you will find that it does not talk about com.android.....
Yet, when you connect from your mobile device, the Android Java version is used and it obviously contains Android specific objects of class com.android.org.conscrypt.OpenSSLRSAPublicKey. The server does not have these class definitions anywhere in its library, so it cannot deserialize them.
Rather then de-/serializing the Java key objects, you should send the plain keys around.
I have a problem that I do not quite understand. I have a server socket and a client socket on two separate machines. Server will constantly sends out data in hex and connected client will read the data stream and do some work.
Most of the traffic is happening in that manner. On a few rare occasions, client will send a bytestring to Server. At this point, I am getting
Java.io.StreamCorruptedException at this line:
ObjectInputStream in = new
ObjectInputStream(socketFromClient.getInputStream());
Exception:
java.io.StreamCorruptedException: invalid stream header: 020001B5
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:857)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:349)
at ReadInput.run(ReadInput.java:21)
at java.lang.Thread.run(Thread.java:745)
"020001B5" is exactly the bytestring that client is sending over to server.
I do not understand why I am getting this StreamCorruptedException. My
code logic does not have any "stream header". What is stream header?
I checked javadoc and I could not make out of why this is happening.
Any tip much appreciated.
thanks
-v
Your client is not writing data using ObjectOutputStream: that's why you're seeing this exception. ObjectOutputStream and ObjectInputStream are used for serializing and deserializing Java objects.
Instead of using ObjectInputStream to read data, consider using BufferedReader or a DataInputStream.
See this example for more details.
I'm writing a Java code which have to send some data to an elecronic system and to receive some data from it through wireless. The electronic system is made of PIC32 and RN-171 module. I'm now trying to connect to the RN-171 network and to send and receive some data. Although I can in my java code set up an OutputStream and send some data to the RN-171 properly, I can't set up an InputStream and my app launches the following exception:
java.io.StreamCorruptedException: invalid stream header: 2A48454C
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:804)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:299)
at TestController.sendParametersToWirelessModule(TestController.java:44)
at TestController.main(TestController.java:30)
The code in my java app, which generates the exception is:
try{
//1. creating a socket to connect to the server
requestSocket = new Socket("1.2.3.4", 2000);
System.out.println("Connected to localhost in port 2004");
//2. get Input and Output streams
out = new ObjectOutputStream(requestSocket.getOutputStream());
out.flush();
--> in = new ObjectInputStream(requestSocket.getInputStream());
//3: Communicating with the server
sendMessage(message); }
(The arrow indicates the code line which generates exception)
Is there a solution? Could anyone help me please?
Thanks
Use the following code instead:
out = requestSocket.getOutputStream();
in = requestSocket.getInputStream();
ObjectOutputStream/ObjectInputStream are used to serialize/deserialize Java objects. There is also no point in flushing the output stream before writing to it.
I have an application with client server architecture. The client
use Java Web Start with Java Swing / AWT and the sert uses HTTP server / Servlet with
Tomcat.
The communication is made from the serialization of objects, create a
ObjectOutput serializes a byte array and send to the server
respectively called the ObjectInputStream and deserializes.
The application follows communicating correctly to a certain
time of concurrency where starting to show error
"SocketException read timeout". The erro happens when the server invoke the method
ObjectInputStream.getObject() in my servlet doPost method.
The tomcat will come slow and the errors start to decrease server response time until the crash time where i must restart the server and after everything works.
Someone went through this problem ?
Client Code
URLConnection conn = url.openConnection();
conn.setDoOutput(true);
OutputStream os = conn.getOutputStream();
ObjectOutputStream oss = new ObjectOutputStream(os);
oss.writeUTF("protocol header sample");
oss.writeObject(_parameters);
oss.flush();
oss.close();
Server Code
ObjectInputStream input = new ObjectInputStream(_request.getInputStream());
String method = input.readUTF();
parameters = input.readObject();
input.readObject() is where the error is
You haven't given us much information to go on, especially about the client side. But my suspicion is that the client side is:
failing to setting the Content-length header (or setting it to the wrong value),
failing to flush the output stream, and/or
not closing the output side of the socket.
Mysterious.
Based on your updated question, it looks like none of the above. Here are a couple of other possibilities:
For some reason the client side is either locking up entirely during serialization or taking a VERY LONG TIME.
There is a proxy between the client and server that is causing problems.
You are experiencing load-related network problems, or network hardware problems.
Another possible explanation is that you have a memory leak, and that the slowdown is caused by the GC taking more and more time as you run out of memory. This will show up in the GC logs if you have them enabled.
I think During high Concurrency, the Socket Timeout set in Tomcat is Expired and the connection is closed. The next read by Tomcat for that connection is greater than the server socket timeout specified in the server.
If you want to avoid this problem you have to increase the timeout on the server-side which is expired in your case. But not advisable.
BTW you did not give enough information. Did you increase the no of threads for connection in Tomcat? If you did, this surely would happen.