0

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?

6

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.