将Python网络代码转换为J

2024-09-25 00:25:17 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我现在想在Java中做同样的事情。例如,我想读取地址0x10000003处长度为0x1的内存,例如1字节。你知道吗

到目前为止,我编写了以下代码:

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);
    }
}

建立连接是可行的,但是在发送数据之后,没有响应。服务器没有发回任何东西,我的Java程序被困在readLine()。输出如下:

Connected
Receiving

read()替换readLine()没有帮助。使用带有writewriteInt调用的DataOutputStream也不起作用。你知道吗

我在这里遇到的困难似乎是准备并正确发送请求数据。作为参考,Python函数^{}^{}中生成以下结果:

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

两个整数都转换为十六进制,并“压缩”为字节数组。你知道吗

readmem命令字符串被转换为ASCII字节数组,我相信:

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

后一个用于打印字节的代码取自here。你知道吗

那么Java代码有什么问题呢?你知道吗


Tags: importselfnewreadreturnif字节address
1条回答
网友
1楼 · 发布于 2024-09-25 00:25:17

您应该使用DataOutputStream而不是PrintWriter。请密切注意文档writewriteByte方法发送一个字节,而writeInt发送四个字节。类似地,读取应该使用DataInputStream,特别是readBytereadFully方法,而不是BufferedReader。你知道吗

作者和读者处理的是文本,而不是字节。PrintWriter.print打印发送数字的ASCII表示,而不是字节本身。BufferedReader(和大多数阅读器)将尝试将传入的字节解码为文本,而不是直接读取字节。你知道吗

相关问题 更多 >