-1

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.

stefan.mih
  • 96
  • 5
  • Most likely you did not completely read the message yet, it may need multiple calls to `inputStream.read` and you have to consider the `num` before trying to read from that buffer, as it will contain junk after the useful data. – Thilo Oct 30 '20 at 23:36
  • Why do you add that buffer anyway? Cannot just do `new ObjectInputStream(inStream)` directly ? – Thilo Oct 30 '20 at 23:37
  • 2
    Why don't you use a BufferedInputStream rather than handling the buffer yourself? – NomadMaker Oct 30 '20 at 23:38
  • It is code from other application that i just upgraded and leaved like that, anyway that works fine and messages are readed when i send regular bytes created from string for example, i tried to call that multiple times and still same, i can send file to server, server can send file to me, but only server can read files, not me (i am client on other pc, server is on main pc where i created project) – stefan.mih Oct 30 '20 at 23:39
  • Well, that code is broken. You cannot read from an InputStream like this. If it blocks at any time, a single `read` call will not give you the whole message. This may not happen if everything is local or in-memory, but over the network it will. If the data is bigger than a single buffer, I won't work either. https://stackoverflow.com/questions/45837998/how-much-data-does-inputstream-read-reads-in-java https://stackoverflow.com/questions/1264709/convert-inputstream-to-byte-array-in-java?rq=1 – Thilo Oct 30 '20 at 23:51
  • Alright i will change this but why this also wont work on same machine where i created project but i export it as jar and run jars? @Thilo – stefan.mih Oct 31 '20 at 11:06

1 Answers1

0

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 :

  1. Read 2(or more) first bytes and detect size of packet.
  2. 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)
  3. Pass the packet to ObjectInputStream and read object !
Alireza Akhoundi
  • 219
  • 2
  • 12