簡體   English   中英

如何從Java網絡獲取某些數據類型作為消息ID

[英]How to get certain data types from Java networking as the message id

我正在研究由GameMaker工作室制作的多人游戲。 我已經在游戲制造商中創建了一個服務器和一個客戶端,這工作正常,但是由於必須使用DirectX,因此無法在任何虛擬機上運行游戲制造商服務器。

因此,我想用Java重寫服務器,這將為我擴展很多選擇。 我看過許多教程,但只看到人們發送“字符串”作為消息,我想用字節代替。 因為在我在GameMaker中創建的服務器中,所以我使用消息ID來標識每個消息應引用的位置。 這些是我閱讀的內容:

buffer_seek(buffer, buffer_seek_start, 0);
var mid = buffer_read(buffer, buffer_u8);
switch(mid) {

    case 0: 

但是據我所知,在Java中只有一個輸入流。 我將如何像下面的代碼一樣拆分該消息:(GameMaker的(服務器的)網絡異步事件)

    case network_type_data:

var buffer = ds_map_find_value(async_load, "buffer");
var socket = ds_map_find_value(async_load, "id");

buffer_seek(buffer, buffer_seek_start, 0);
var mid = buffer_read(buffer, buffer_u8);
switch(mid) {

    case 0: 
    //let's updated the first information we can get whether the user is registering or loging in
    //Reads what username was assigned to player
    var username = buffer_read(buffer, buffer_string);
    //Updates information of players
    UpdatePlayerInfo("name", username, socket);
    SendRoomList(1, socket);
    break;

    case 1: //player wants to create a server
    //find the name of the player
        show_debug_message("a player created a room");
       if(Room_exists(socket) == false and PlayerInRoom(socket) == false) {
        var Room = CreateRoom(socket, 2);


        JoinRoom(socket, Room);  
        SendRoomList(1, socket);
    }
    break;

    case 2: //player wants to join the server

     var desired_room = buffer_read(buffer, buffer_u8); 
     if(PlayerInRoom(socket) == false) {
     JoinRoom(socket, desired_room);
     }

    break;



    }
}

Java的ByteBuffer是一個能夠從簡單流中獲取String以外的項目的良好起點。 本質上,您將TCP輸入流中的一部分字節捕獲到ByteBuffer實例中,並且可以調用getInt(),getDouble()和其他類似方法從中獲取原始類型。

這是它的一些用法,類似於問題中的腳本。

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;


public class JavaIo {

    // number of bytes in a user name
    private static final int SIZE_OF_USER_NAME = 30;
    // number of bytes in the internal buffer
    private static final int BUFFER_SIZE = 1024;

    public void workWithConnection() {
        final int portNumber = 12345; // TODO: read this from config file or command line arguments instead
        try (
                ServerSocket server = new ServerSocket(portNumber);
                Socket connection = server.accept();
                SocketChannel channel = connection.getChannel();
        ) {
            final ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
            channel.read(buffer);   // fill buffer from the input stream
            // since your buffer in GameMaker is unsigned, let's prevent all that signed to unsigned nonsense by doing a
            // bitmask
            final int mid = buffer.get() & 0x000000FF;
            switch(mid) {
                case 0:
                    // grab some bytes from the buffer and change them into a String
                    final byte[] usernameBytes = new byte[SIZE_OF_USER_NAME];
                    buffer.get(usernameBytes);
                    final String username = new String( usernameBytes, Charset.forName(StandardCharsets.UTF_8.name()));
                    // ...
                    break;
                case 1:
                    // grab 4 bytes from the buffer and change it into an integer
                    final int roomId = buffer.getInt();
                    // ...
                    break;
                default:
                    // ...
            }
        } catch(IOException ioe) {
            // TODO: handle exception
        }
    }

}

參考文獻:

在Java中將字節數組轉換為整數,反之亦然

http://www.ibm.com/developerworks/java/tutorials/j-nio/j-nio.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM