BullyWiiPlaza
BullyWiiPlaza

Reputation: 19195

Converting Python Networking Code To Java

Given the following function definitions in Python:

class NetworkClient:
    def __init__(self, ip):
        self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM, socket.IPPROTO_TCP)
        self.s.connect((str(ip), 7331))

    def readmem(self, address, length):
        if length == 0: raise BaseException, "Why are you giving me no length" #Please don't do this to me
        if not self.ValidMemory().validrange(address, length): return
        if not self.ValidMemory().validaccess(address, length, "read"): return
        self.s.send("\x04") #cmd_readmem
        request = struct.pack(">II", address, address + length)
        self.s.send(request)
        status  = self.s.recv(1)
        if status == "\xbd": #Non-zero memory was found
            response = self.s.recv(length)
        elif status == "\xb0": #All zeroes
            response = "\x00" * length
        else: return #Something went terribly wrong
        return response

I now want to do the same in Java. As example I want to read the memory at address 0x10000003 with length 0x1 e.g. 1 byte.

So far I wrote the following code:

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class NetworkClient
{
    public static void main(String[] arguments) throws IOException, InterruptedException
    {
        try (Socket clientSocket = new Socket("192.168.178.35", 7331);
             PrintWriter outputWriter =
                     new PrintWriter(clientSocket.getOutputStream(), true);
             BufferedReader inputReader =
                     new BufferedReader(
                                               new InputStreamReader(clientSocket.getInputStream())))
        {
            System.out.println("Connected");

            byte readMemoryCommand = (byte) 4;
            int memoryAddress = 0x10000003;
            int length = 0x1;

            outputWriter.print(readMemoryCommand);
            outputWriter.print(memoryAddress);
            outputWriter.println(memoryAddress + length);

            System.out.println("Receiving");
            System.out.println(inputReader.read());
            System.out.println("Received");
        }
    }

    public static byte[] toByteArray(String letters)
    {
        return letters.getBytes(StandardCharsets.US_ASCII);
    }
}

Establishing the connection works but then after sending the data, there is no response. The server does not send anything back and my Java program is stuck on readLine(). The output is as follows:

Connected
Receiving

Replacing readLine() with read() does not help. Using a DataOutputStream with write and writeInt calls does not work either.

The difficulty I'm having here seems to be to prepare and send the request data correctly. For your information, the Python function struct.pack produces the following result in an interactive Python session:

>>> import struct
>>> struct.pack(">II", 10000003, 10000004)
b'\x00\x98\x96\x83\x00\x98\x96\x84'
>>>

Both integers are converted to hexadecimal and "packed" into a byte array.

The readmem command String is converted to an ASCII byte array I believe:

>>> print("\x04")
*Box with questionmark in it*
>>> s = "04"
>>> ":".join("{:02x}".format(ord(c)) for c in s)
'30:34'
>>>

The latter code for printing the bytes is taken from here.

So what is wrong with the Java code?

Upvotes: 0

Views: 195

Answers (1)

VGR
VGR

Reputation: 44338

You should be using DataOutputStream instead of PrintWriter. Pay close attention to the documentation—the write and writeByte methods send one byte, while writeInt sends four bytes. Similarly, reading should be done with a DataInputStream, specifically the readByte and readFully methods, rather than BufferedReader.

Writers and Readers deal with text, not bytes. PrintWriter.print sends an ASCII representation of a number, rather than the byte itself. BufferedReader (and most Readers) will try to decode the incoming bytes into text, instead of reading the bytes directly.

Upvotes: 1

Related Questions