reading bytearray upto specified location - java

Let me allow to describe my problem:
I have created socket server in python and client in java, from java I am sending multiple objects to server by using :
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ByteArrayOutputStream append = new ByteArrayOutputStream();
ObjectOutput out = null;
byte finalarr[]=null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(object);
out.flush();
byte[] objByte = bos.toByteArray();
bos.close();
out.close();
append.write(objByte.length);
append.write(objByte);
bos = new ByteArrayOutputStream();
out = new ObjectOutputStream(bos);
out.writeObject(value);
out.flush();
append.write(bos.toByteArray());
finalarr = append.toByteArray( );
os = sChannel.socket().getOutputStream();
oos = new ObjectOutputStream(os);
oos.write(finalarr);
} finally {
try {
bos.close();
} catch (IOException ex) {
}
}
Now, finalarr contains byte length of object then actual byte[] of object and then byte[] of value. Now in python after receiving this First I want to read length of byte which is written in first position of finalarr then whatever length I get I want to read received array upto that length so that I will get object separately then the remaining part separately.
In python I have done upto this:
total_data=b''
while True:
data = self.clientsocket.recv(1024)
if not data: break
total_data += data
In total_data I am getting entire bytearray, but I don't know how I can read it so that I can get two objects separately as explained.

Related

Different bytes read from which I wrote

I'm trying to write a byte array to file and then to read it again. The problem is that the byte array that I Read is different from that I wrote.
The output of the code below is:
[B#21a06946 (Original byte array written)
[B#2fc14f68 (byte array read )
byte[] encryptedKey = rsaCipher.encrypt(AESKey, publicKeyPathName, transformation, encoding);
System.out.println(encryptedKey);
List<byte[]> list = new ArrayList<byte[]>();
list.add(encryptedKey);
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("encryptedKey"));
out.writeObject(list);
out.close();
ObjectInputStream in = new ObjectInputStream(new FileInputStream("encryptedKey"));
List<byte[]> byteList = (List<byte[]>) in.readObject();
in.close();
byte[] encryptedKey2 = byteList.get(0);
System.out.println(encryptedKey2);
Arrays do not have a proper String representation. To see the content, use the below instead
System.out.println(java.util.Arrays.toString(encryptedKey));
System.out.println(java.util.Arrays.toString(encryptedKey2));

Java server sending byte array over TCP socket to Android clients

I have a server device and N client devices. I want to send pictures to each client from the server.
My problem is the client doesn't receive the whole image. I converted the Bitmaps to byte array before I send it.
Send Bitmaps on the Server:
try {
OutputStream out = clients.get(i).getSocket().getOutputStream();
//Convert Bitmap to byte array:
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(CompressFormat.JPEG, 70, stream);
byte[] byteImage = stream.toByteArray();
//Send the byte array
if(byteImage.length > 0){
out.write(byteImage, 0, byteImage.length);
out.flush();
}
out.close();
} catch (IOException e) {
e.printStackTrace();
}`
Receive image on the Client:
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] data = new byte[1024];
int length = 0;
while ((length = in.read(data)) != -1) { //in --> InputStream
out.write(data, 0, length);
out.flush();
}
byte[] bytePicture = out.toByteArray();
out.close();
} catch (IOException e) {
}
Before I send the image, I tell the size of the byte array of the Bitmap to the clients.
My problem is the received bytes < send bytes. Why?
On the server side I created threads for all clients to send the images them.
EDIT:
I use PrintWriters to communicate with messages between the server and the clients.
I send the length of the byte array from the server to the clients before I start to send the byte array.
PrintWriter writer;
writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(out)), true);
writer.println("BYTE#" + byteImage.length);
writer.flush();
When a client get a message, which starts with "BYTE#" on the client side, I start to read the byte array:
reader = new BufferedReader(new InputStreamReader(inputStream));
final String message = reader.readLine();
if (message != null && message.startsWith("BYTE#")){
//Get the length of the byte array (correct)
int length = Integer.valueOf(message.split("#")[1]);
//... Start to read the byte array here...
}

Deserializable exception : local class is not compatible cause of serialVersionID

Here is my code:
MyOwnObject deserializedObject = null;
try{
ByteArrayInputStream bis = new ByteArrayInputStream(serializedObject.getBytes());
ObjectInputStream ois= new ObjectInputStream(bis);
deserializedObject = (MyOwnObject)ois.readObject();
ois.close();
}catch(Exception e){
e.printStackTrace();
}
someMapper.insert(deserializedObject);
PS: serializedObject is a string which i get from serialization process before, and it's working well i think.
The code throws an exception:
local class incompatible: stream classdesc serialVersionUID = 1360826667802527544, local class serialVersionUID = 1360826667806852920
And in the stacktrace there's something about the type Integer of some attribute in my object.
UPDATE:
serializeObject is a string,from this code:
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bo);
so.writeObject(myObject);
so.flush();
serializedObject = bo.toString();
}catch (Exception e) {
System.out.println(e);
}
ANSWER:
//Serialization from object to string
String serializedObject="";
try{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
serializedObject = new String(Base64.encode(baos.toByteArray()));
oos.close();
}catch(Exception e){
e.printStackTrace();
}
//Deserialization from string to object
MyOwnObject deserializedObject = null;
try{
byte[] bytes = Base64.decode(serializedObject.getBytes());
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
ObjectInputStream ois = new ObjectInputStream(bais);
deserializedObject = (MyOwnObject)ois.readObject();
ois.close();
}catch(Exception e){
e.printStackTrace();
}
From here,i can use deserializedObject as an object,and it worked well!
The problem is in how you create your serializedObject.
You use a ByteArrayOutputStream. You shouldn't call toString() on it. Instead call its toByteArray() method to get the underlying data as a byte array, and you can use that to create your ByteArrayInputStream and it will work.
Example:
// Serialization
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream so = new ObjectOutputStream(bo);
so.writeObject(myObject);
so.flush();
byte[] serializedObject = bo.toByteArray();
// Deserialization
MyOwnObject deserializedObject = null;
try {
ByteArrayInputStream bis = new ByteArrayInputStream(serializedObject);
ObjectInputStream ois = new ObjectInputStream(bis);
deserializedObject = (MyOwnObject)ois.readObject();
ois.close();
} catch (Exception e){
e.printStackTrace();
}
A serialized object is a sequence of bytes (a byte array) and not a sequence of characters. You cannot create a String from the bytes of a serialized object, because it may not contain valid unicode codepoints for example.
If you really need to represent the serialized object as a String, try representing the byte array in hex string or use base64 encoding.
besides base64, you can use hex string also!i always use it when i encounter a similar problems!

How to write part of header using BufferedOutputStream?

I want to write a ~20000 bytes to a replace the same number of bytes of file at offset OFFSET using a BufferedOutputStream. I try to do this with the following code:
headerOffset = 12000;
headerSize = 20000;
byte[] ba = new byte[20];
FileOutputStream os;
BufferedOutputStream bos;
try {
os = new FileOutputStream('file.dat');
bos = new BufferedOutputStream(os);
bos.write(ba, headerOffset, headerSize);
os.flush();
} catch (IOException e) { e.printStackTrace(); }
However, this results in the 'file.dat' being overwritten by the contents of ba overwriting the entire file and leaving it only as big as ba. What am I doing wrong?

Receive byte[] using ByteArrayInputStream from a socket

Here is the code but got error:
bin = new ByteArrayInputStream(socket.getInputStream());
Is it possible to receive byte[] using ByteArrayInputStream from a socket?
No. You use ByteArrayInputStream when you have an array of bytes, and you want to read from the array as if it were a file. If you just want to read arrays of bytes from the socket, do this:
InputStream stream = socket.getInputStream();
byte[] data = new byte[100];
int count = stream.read(data);
The variable count will contain the number of bytes actually read, and the data will of course be in the array data.
You can't get an instance of ByteArrayInputStream by reading directly from socket.
You require to read first and find byte content.
Then use it to create an instance of ByteArrayInputStream.
InputStream inputStream = socket.getInputStream();
// read from the stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] content = new byte[ 2048 ];
int bytesRead = -1;
while( ( bytesRead = inputStream.read( content ) ) != -1 ) {
baos.write( content, 0, bytesRead );
} // while
Now, as you have baos in hand, I don't think you still need a bais instance.
But, to make it complete,
you can generate byte array input stream as below
ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );

Categories