簡體   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