0

From my client side, I was sending an integer of the size of the variable to the server, when I got it on the server, it was in a different format of data than what I need, how do I decode it?

Client side code when sending

Socket s = new Socket();
s.connect(new InetSocketAddress(voids[1], 7800), 2000);
DataOutputStream writer = new DataOutputStream(s.getOutputStream());
data.remove("ObjectStream");
writer.write(9); // used 9 for testing
writer.flush();

Server side for receiving

amt = client.recv(self.SIZE) # size is 1024
amt = amt.decode() # where it should have decode and get 9

integer values with received values on server side:

  • 1 -> b'\01'
  • 2 -> b'\02'
  • 3 -> b'\03'
  • 8 -> b'\08'
  • 9 -> b'\t'
  • 10 -> b'\n'
SeanLink11
  • 23
  • 1
  • 8
  • A `DataOutputStream` uses a very specific serialization protocol (similar to XDR). Are you sure you don't want to use a plain `OutputStream`. However, the output you show would not be produced by just that code. Please provide a [mre]. – Mark Rotteveel Oct 25 '20 at 11:57
  • Calling only `write(9)` on a `DataOutputStream` would produce only the byte `9`, nothing more. So either this is not a `java.io.DataOutputStream`, or you are writing more data before and after doing this `write(9)`. You may also want to specify what outcome you actually expect. – Mark Rotteveel Oct 25 '20 at 12:05
  • Are are you confused about the mapping of 9 to `b'\t'`? That is because byte 9 is the tab character (or `\t`), and byte 10 is the newline character (`\n`), etc. – Mark Rotteveel Oct 25 '20 at 12:15
  • @MarkRotteveel oh, so what do I have to do to send 9 instead of the tab value? – SeanLink11 Oct 25 '20 at 12:16
  • 1
    When sending 9 as a byte, it is indistinguishable from the tab character. Python just happens to show it as `b'\t'`. It might be better if you explain what you are expecting. Maybe you want to send the **character** '9', and not the byte 9? – Mark Rotteveel Oct 25 '20 at 12:18
  • @MarkRotteveel I want to send the integer 9 – SeanLink11 Oct 25 '20 at 12:20
  • Then use `writeInt(9)` and follow [Convert bytes to int?](https://stackoverflow.com/questions/34009653/convert-bytes-to-int). `DataOutputStream` writes ints in network byte order (big endian). For example: `int.from_bytes(b'\x00\x00\x00\t', byteorder='big', signed=True)` produces 9. – Mark Rotteveel Oct 25 '20 at 12:22
  • @MarkRotteveel It works, thank you, I used writeInt() to send and decode it using int.from_bytes(amt, byteorder="big") and I got the value – SeanLink11 Oct 25 '20 at 12:28

2 Answers2

-1

for anything which you want to send with sockets must be converted to a particular format so use the function writeInt() -

DataOutputStream writer =
(DataOutputStream)data.get("ObjectStream");
data.remove("ObjectStream");
writer.writeInt(9); // used 9 for testing
Yeshwin Verma
  • 282
  • 3
  • 16
  • Did you mean [`writeByte`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/DataOutputStream.html#writeByte(int))? BTW:, [`write`](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/io/DataOutputStream.html#write(int)) will write a single byte as well, but, contrary to `writeByte`, it will not increase the counter of bytes written that a `DataOutputStream` keeps. – Mark Rotteveel Oct 25 '20 at 11:58
  • But the function writeBytes() only accepts String input, I also tried writeByte() and it gives the same result – SeanLink11 Oct 25 '20 at 12:03
  • Sorry for the mistake it's writeInt(). Check my answer I have updated it – Yeshwin Verma Oct 25 '20 at 12:04
  • @MarkRotteveel What does the counter of bytes do? – SeanLink11 Oct 25 '20 at 12:05
  • Sorry for the mistake it's writeInt(). Check my answer I have updated it – Yeshwin Verma Oct 25 '20 at 12:05
  • @SeanLink11 It can be useful if you need to write length prefixed messages. You first write the message using a `DataOutputStream` to a temporary location, then use `DataOutputStream.size()` to determine the size, and then you write the size + message to the actual destination. – Mark Rotteveel Oct 25 '20 at 12:07
  • @YeshwinVermaTheProgrammer I tried writeInt() and it gives b'\x00\x00\x00\t' when I send 9 – SeanLink11 Oct 25 '20 at 12:08
  • @SeanLink11 That is the correct output for writing a 32-bit int with value 9 (four bytes: 0, 0, 0, 9). You really should specify what you actually expect. – Mark Rotteveel Oct 25 '20 at 12:09
  • @SeanLink11 what do you mean "it can be useful" it works just fine with it. Please explain in detail what do you want to say. – Yeshwin Verma Oct 25 '20 at 12:10
  • @YeshwinVermaTheProgrammer I was the one that said "it can be useful", not SeanLink11, and I was referring to the number of bytes written that is tracked by a `DataOutputStream`. – Mark Rotteveel Oct 25 '20 at 12:11
  • I think you should follow this tutorial https://www.codejava.net/java-se/networking/java-socket-server-examples-tcp-ip – Yeshwin Verma Oct 25 '20 at 12:14
  • Sending 9 as a 32-bit integer is no better than sending 9 as an 8-bit integer. – President James K. Polk Oct 25 '20 at 13:49
-1

Solved (credit to @MarkRotteveel):

Client side send

Socket s = new Socket();
s.connect(new InetSocketAddress(voids[1], 7800), 2000);
DataOutputStream writer = new DataOutputStream(s.getOutputStream());
data.remove("ObjectStream");
writer.writeInt(9); // used 9 for testing
writer.flush();

Socket Receive and Decode

amt = client.recv(self.SIZE)
amt = int.from_bytes(amt, byteorder="big")
amt = amt.decode()
SeanLink11
  • 23
  • 1
  • 8
  • You should use `int.from_bytes(amt, byteorder="big", signed=True)`, otherwise you won't be able to correctly decode negative values. – Mark Rotteveel Oct 25 '20 at 12:31
  • Even though 4 bytes were sent, there is no guarantee you will receive 4 bytes in `client.recv(self.SIZE)`. See [this](https://stackoverflow.com/a/43420503/238704) answer. – President James K. Polk Oct 25 '20 at 13:51