Java PrintWriter Not sending Byte Array - java

A byte array of unknown size is needed to be sent over a socket. When i try to write the byte array to printwriter like
writeServer = new PrintWriter(socketconnection.getOutputStream());
writeServer.flush();
writeServer.println("Hello World");
writeServer.println(byteArray.toString());
It is received at the server but is only a string of 5-6 characters always starting from [B#..... But when i send it through the output stream like
writeServer.println("Hello World");
socketconnection.getOutputStream().write(byteArray);
It is received at the server correctly. But the issue is in the second option the "Hello World" String does not go through to the server. I want both of things delivered to the server.
How should i do it?

You are trying to mix binary and text which is bound to be confusing. I suggest you use one or the other.
// as text
PrintWriter pw = new PrintWriter(socketconnection.getOutputStream());
pw.println("Hello World");
pw.println(new String(byteArray, charSet);
pw.flush();
or
// as binary
BufferedOutputStream out = socketconnection.getOutputStream();
out.write("Hello World\n".getBytes(charSet));
out.write(byteArray);
out.write(`\n`);
out.flush();

byteArray.toString() will return you human readable form of byteArray. Even though for Arrays it is never human readable.
If you want to transfer byteArray as String then you should use
String str = new String(bytes, Charset.defaultCharset());//Specify different charset value if required.

Related

GZIPInputStream unable to decode at receiver side (invalid code lengths set)

I'm attempting to encode a String in a client using GZIPOutputStream then decoding the String in a server using GZIPOutputStream.
The client's side code (after the initial socket connection establishment) is:
// ... Establishing connection, getting a socket object.
// ... Now proceeding to send data using that socket:
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
String message = "Hello World!";
ByteArrayOutputStream out = new ByteArrayOutputStream();
GZIPOutputStream gzip = new GZIPOutputStream(out);
gzip.write(message);
gzip.close();
String encMessage = out.toString();
out.writeInt(encMessage.getBytes().length);
out.write(encMessage.getBytes());
out.flush();
And the server's side code (again, after establishing a connection):
DataInputStream input = new DataInputStream(socket.getInputStream());
int length = input.readInt();
byte[] buffer = new byte[length];
input.readFully(buffer);
GZIPInputStream gz = new GZIPInputStream(new ByteArrayInputStream(buffer));
BufferedReader r = new BufferedReader(new InputStreamReader(gz));
String s = "";
String line;
while ((line = r.readLine()) != null)
{
s += line;
}
I checked and the buffer length (i.e., the coded message's size) is passed correctly, so the right number of bytes is transferred.
However, I'm getting this:
java.util.zip.ZipException: invalid code lengths set
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:164)
at java.util.zip.GZIPInputStream.read(GZIPInputStream.java:117)
at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:122)
at parsing.ReceiveResponsesTest$TestReceiver.run(ReceiveResponsesTest.java:147)
at java.lang.Thread.run(Thread.java:745)
Any ideas?
Thanks in advance for any assistance!
You're calling toString() on the ByteArrayOutputStream - that is incorrect, and it opens up all kinds of character encoding problems that are probably biting you here. You need to call toByteArray instead:
byte[] encMessage = out.toByteArray();
out.writeInt(encMessage.length);
out.write(encMessage);
Detail:
if you use toString(), Java will encode your bytes in your platform default character encoding. That could be some Windows codepage, UTF-8, or whatnot.
However not all characters can be encoded properly, and some will be replaced by an alternative character - a question mark perhaps. Without knowing the details, it's hard to tell.
But in any case, encoding the byte array to a String, and then decoding it to a byte array again when you write it out, is very likely to change the data in the byte array. And there is not need to do it, you can just get the byte array straight away as shown in the code above.
Why on earth are you indulging in all this complication? You can reduce it all to this:
GZIPOutputStream gzip = new GZIPOutputStream(socket.getOutputStream());
DataOutputStream out = new DataOutputStream(gzip);
String message = "Hello World!";
out.writeUTF(message);
out.close();
// ...
GZIPInputStream gz = new GZIPInputStream(new ByteArrayInputStream(socket.getInputStream()));
DataInputStream input = new DataInputStream(gz);
String line = input.readUTF();
I further note that your code doesn't actually compile. I would further note that unless the messages are several orders of magnitude larger, there is no benefit to the GZipping.

Byte array reading

I have a problem with writing an reading an array of bytes from client to server. The client actually writes all the bytes but the server does not seem to be able to read it. Here is the code for the client and server sides
Socket sock = new Socket(Interface.SERVER_IP, 4444);
PrintStream os = new PrintStream(sock.getOutputStream());
os.println("3");
DataOutputStream dOut = new DataOutputStream(sock.getOutputStream());
dOut.writeInt(data.length); // byte array created above
dOut.write(data);
and the server side is:
DataInputStream clientData = new DataInputStream(clientSocket.getInputStream());
int length = clientData.readInt();
System.out.println(length);
byte[] data = new byte[length]; // read length of incoming message
if(length>0) {
clientData.readFully(data, 0, data.length); // read the message
}
The server seems to be blocked at the line to read the length of the byte array. Please I really need help solving this
After you write the data, flush the output:
dOut.writeInt(data.length); // byte array created above
dOut.write(data);
dOut.flush();
Alternatively, close the stream (if you aren't going to use it again)...
dOut.writeInt(data.length); // byte array created above
dOut.write(data);
dOut.close();
Also note that your PrintWriter is printing a string value (of "3"). You are printing extra data to the stream that doesn't seem to get consumed on the server.
You're printing "3" to the socket but you're never reading it. So when you do readInt(), you're reading the "3" and a line terminator instead.
Don't mix multiple streams/writers on the same socket. Use the same ones for the life of the socket.

how to stream jpeg frame from java client to python server

i am developing an android application wherein i have to send a frame in jpeg format allocated to a BufferedArrayOutputStream (baos variable in code). I convert this baos into a byte array to write into the socket.
On the server side i would like to reconstruct the image in jpeg format. If i write the data received in a variable to a '.jpg' file on the server, on opening the file, it gives an error like "file starting with ffx0 not jpeg format". I think this is because the string variable in python writes the data in the file as a hex string.
The client code is as follows :-
Bitmap memoryImage = Bitmap.createBitmap(rgb, previewSize.width,previewSize.height,Bitmap.Config.ARGB_8888);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if(memoryImage.compress(CompressFormat.JPEG,100, baos)){
try {
if(count==0){
byte [] Finalbaos = baos.toByteArray();
int tempLen = Finalbaos.length;
Log.v("Client","ImageBytes :"+ tempLen);
String dataMeta = Integer.toString(tempLen);
Log.v("Client","Integer Size :"+ dataMeta.length());
PrintWriter tempOut = new PrintWriter(socket.getOutputStream());
if(tempOut!=null){
tempOut.write(dataMeta);
Log.v("Client","data size sent");
tempOut.flush();
}
DataInputStream in = new DataInputStream(socket.getInputStream());
if(in!=null){
Log.v("Client","read buffer created");
String xyz = in.readLine();
String temp = "recvd";
Log.v("Client",xyz);
if(xyz.equals(temp)){
OutputStream out = socket.getOutputStream();
out.write(Finalbaos,0,tempLen);
out.flush();
Log.d("Client", "Client sent message");
}
}
server code:
import socket,thread
import string
import array
host=""
port=54321
s=socket.socket()
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
s.bind((host,port))
s.listen(5)
conn,address=s.accept()
data=""
mylen=0
dataRecv=0
file1 = open("myfile.jpg","w")
totalLength=""
length=conn.recv(1024)
conn.send("recvd")
mylen=int(length)
while dataRecv<mylen:
newData=""
newData=conn.recv(1)
if not newData:
break
data+=newData
dataRecv+=len(newData)
result= array.array('B',data.decode("hex"))
file1.write(result)
file1.close()
print len(data)
conn.close()
s.close()
can anyone let me know how to reconstruct the frame on server either in python or C++
mylen=len(length) doesn't give you the length you're trying to send. it gives you how many bytes were read in the previsous recv. So you get the wrong lenght there.
on your client side, you use String xyz = in.readLine(); which will block until a newline character is encountered. but you never send a '\n' on the server side, instead you go waiting for a response from the client. so you have a deadlock there.
you use data.decode("hex") on your recieved data. unless you do the equivalend of data.encode("hex") in java on the other side, that won't work. it should give you an error if the string is not a valid hex-representation of a binary string.
result is an array.array, which you write to file. file1.write expects a string as argument, it gives you an error if you pass your result object.
so i can't even see why your code works at all, and why there's anything at all in your file.

PrintWriter and byte[] problem

byte[] data = (byte[])opBinding.execute();
PrintWriter out = new PrintWriter(outputStream);
out.println(data);
out.flush();
out.close();
but instead of text i get #84654. How can i add byte[] to PrintWriter? I need byte[] and not strinf becouse i have encoing problems with čćžšđ
You can use the outputstream directly to write the bytes.
outputStream.write(byte[] b);
PrintWriter is meant for text data, not binary data.
It sounds like you should quite possibly be converting your byte[] to a String, and then writing that string out - assuming the PrintWriter you're writing to uses an encoding which supports the characters you're interested in.
You'll also need to know the encoding that the original text data has been encoded in for the byte[], in order to successfully convert to text to start with.
The problem is, that your code calls (implicitly) data.toString() before returning the result to your println statement.
try this
byte[] data = (byte[])opBinding.execute();
PrintWriter out = new PrintWriter(outputStream);
out.println(new String(data));
out.flush();
out.close();
It worked for me.. when i used
PrintWriter out=new PrintWriter(System.out);
Also it converts the byte data to String using toString() method.. So it may be a reason for your encoding problem

How can I make sure my server reads what the client has written?

I am writing a byte array from a socket client as:
byte[] arr = { 49, 49, 49, 49, 49};
InetAddress address = InetAddress.getByName(host);
connection = new Socket(address, port);
out = new ObjectOutputStream(connection.getOutputStream());
out.flush();
At receiving end, on the server I have:
byte[] msgType = new byte[5];
in = new BufferedInputStream(connection.getInputStream());
int bytesRead = in.read(msgType, 0, 5);
System.out.println("msg rcvd: " + msgType.toString());
In the output I get weird string:
server: waiting for connection
server: connection received from localhost
server: Connection Successful
bytes read: 5
msg rcvd: ��w
How can make sure I get same bytes as I sent from my client?
I'm not sure exactly what are trying to print out, but I can tell you that msgType.toString() will not print the contents of the byte array.
Here is a link I found to a method which will print out the byte array in a more meaningful fashion.
You're getting the same bytes, it's just a matter of how you interpret them. If you want to see the bytes as a String use this instead:
System.out.println("msg rcvd: " + new String(msgType, "UTF-8"));
Be careful that the bytes you're dealing have the right encoding though (I assumed UTF-8 here). Since you're already ObjectOutputStream though, you could just use its writeUTF() on the server side and ObjectInputStream.readUTF() on the client side.
If you use an ObjectOutputStream on one side, you'll have to use an ObjectInputStream at the other side.
In your case, a simple OutputStream (maybe buffered) and .write() and .read() will do.
But for printing, don't use byte[].toString(), use Arrays.toString() if you want to have a formatted output.
Edit: I just see you are not even writing your array on the sending side. So you are actually only reading the ObjectOutputStream header.
From the comment:
I am handling server side and I am told that I would be send a byte array. How
do I receive and print that byte array ? byte array in this case is bytes of text/strings
This sounds like the server sends something like simply the Strings encoded in some encoding, like ASCII, UTF-8 or ISO-8859-1. If so, on the receiving end you can use something like this:
String encoding = "UTF-8";
BufferedReader in =
new BufferedReader(new InputStreamReader(connection.getInputStream(),
encoding));
String line;
while((line = in.readLine()) != null) {
System.out.println(line);
}
Of course, make sure the encoding is the same encoding as actually used on the sending side.
The corresponding sending code could be something like this:
String encoding = "UTF-8";
Writer w =
new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),
encoding));
w.write("Hello World!\n");
w.write("And another line.\n");
w.flush();

Categories

Resources