繁体   English   中英

Java向我的世界服务器发送握手包

[英]Java sending handshake packets to minecraft server

我一直在研究一个 Java 程序,它的作用基本上类似于 Minechat(基于文本的应用程序,仅用于查看聊天)。我从未真正过多地使用网络,所以问题是弄清楚如何正确发送数据包。 我目前处于与服务器创建握手的位置。 经过数小时的研究,我想出了以下代码,但它总是遇到“失败!(异常)”消息。 对我来说,一切看起来都是正确的,但就我所知,它可能是 100% 错误的。 如果有人能指出我在这里做错了什么,我将不胜感激。

作为参考,请随意使用thisthis

public static void main(String[] args) throws IOException {
    host = new InetSocketAddress("162.244.165.111", 48040);
    socket = new Socket();
    System.out.println("Connecting...");
    socket.connect(host, 3000);
    System.out.println("Done!");
    System.out.println("Making streams...");
    output = new DataOutputStream(socket.getOutputStream());
    input = new DataInputStream(socket.getInputStream());
    System.out.println("Done!");
    System.out.println("Attempting handshake... "+host.getAddress().toString().substring(1));
    byte[] msg = ("47;"+host.getAddress().toString().substring(1)+";"+host.getPort()+";2;").getBytes(Charset.forName("UTF-16"));
    output.writeInt(msg.length+Integer.valueOf(0x00));
    output.writeByte(0x00);
    output.write(msg);
    output.flush();
    try {
        if (input.readByte() != 0x02)
            System.out.println("Failed!");
        else
            System.out.println("Done!");
    } catch (EOFException e) {
        System.out.println("Failed! (Exception)");
    }
}

编辑:更多研究建议我使用 Byte 数组,但这让我对如何表示字符串和需要使用字符串感到困惑?

查看此页面http://wiki.vg/Protocol ,您似乎没有编写足够的数据,也没有按正确的顺序编写。 您还需要使用varint ,它是一种特殊类型的整数数据表示形式。

此问题的相关链接:


状态 ping 的工作原理如下:

 C->S : Handshake State=1 C->S : Request S->C : Response C->S : Ping S->C : Pong

C是客户端,S是服务器

使用 wiki 和提供的代码示例,我修改了您的代码以遵循整个状态请求。

 public static void main(String [] args) throws IOException { String address = "162.244.165.111"; int port = 48040; InetSocketAddress host = new InetSocketAddress(address, port); Socket socket = new Socket(); System.out.println("Connecting..."); socket.connect(host, 3000); System.out.println("Done!"); System.out.println("Making streams..."); DataOutputStream output = new DataOutputStream(socket.getOutputStream()); DataInputStream input = new DataInputStream(socket.getInputStream()); System.out.println("Done!"); System.out.println("Attempting handshake... "+host.getAddress().toString()); byte [] handshakeMessage = createHandshakeMessage(address, port); // C->S : Handshake State=1 // send packet length and packet writeVarInt(output, handshakeMessage.length); output.write(handshakeMessage); // C->S : Request output.writeByte(0x01); //size is only 1 output.writeByte(0x00); //packet id for ping // S->C : Response int size = readVarInt(input); int packetId = readVarInt(input); if (packetId == -1) { throw new IOException("Premature end of stream."); } if (packetId != 0x00) { //we want a status response throw new IOException("Invalid packetID"); } int length = readVarInt(input); //length of json string if (length == -1) { throw new IOException("Premature end of stream."); } if (length == 0) { throw new IOException("Invalid string length."); } byte[] in = new byte[length]; input.readFully(in); //read json string String json = new String(in); // C->S : Ping long now = System.currentTimeMillis(); output.writeByte(0x09); //size of packet output.writeByte(0x01); //0x01 for ping output.writeLong(now); //time!? // S->C : Pong readVarInt(input); packetId = readVarInt(input); if (packetId == -1) { throw new IOException("Premature end of stream."); } if (packetId != 0x01) { throw new IOException("Invalid packetID"); } long pingtime = input.readLong(); //read response // print out server info System.out.println(json); System.out.println("Done!"); } public static byte [] createHandshakeMessage(String host, int port) throws IOException { ByteArrayOutputStream buffer = new ByteArrayOutputStream(); DataOutputStream handshake = new DataOutputStream(buffer); handshake.writeByte(0x00); //packet id for handshake writeVarInt(handshake, 4); //protocol version writeString(handshake, host, StandardCharsets.UTF_8); handshake.writeShort(port); //port writeVarInt(handshake, 1); //state (1 for handshake) return buffer.toByteArray(); } public static void writeString(DataOutputStream out, String string, Charset charset) throws IOException { byte [] bytes = string.getBytes(charset); writeVarInt(out, bytes.length); out.write(bytes); } public static void writeVarInt(DataOutputStream out, int paramInt) throws IOException { while (true) { if ((paramInt & 0xFFFFFF80) == 0) { out.writeByte(paramInt); return; } out.writeByte(paramInt & 0x7F | 0x80); paramInt >>>= 7; } } public static int readVarInt(DataInputStream in) throws IOException { int i = 0; int j = 0; while (true) { int k = in.readByte(); i |= (k & 0x7F) << j++ * 7; if (j > 5) throw new RuntimeException("VarInt too big"); if ((k & 0x80) != 128) break; } return i; }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM