java - 如何从Java网络获取某些数据类型作为消息id

标签 java gml

我正在开发多人游戏,该游戏是在 GameMaker 工作室中创建的。我已经在 gamemaker 中创建了一个服务器和一个客户端,工作得很好,但是 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
        }
    }

}

引用文献:

Convert a byte array to integer in java and vice versa

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

关于java - 如何从Java网络获取某些数据类型作为消息id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37237018/

相关文章:

java - 如何修改或重新训练现有的 OpenNLP 模型?

java - 在 JBOSS 中部署 JAR

java - Apache Ivy 依赖项强制 ="true"不起作用

python - 如何从 GML 文件中提取数据

java - Hibernate 序列化中的字符串到 GML 对象

java - 在 Java 中解析 GML 时出现错误字符

java - 防止 css 经历 reSTLet

java - 将给定时间转换为 GMT

geoserver - 在 GeoServer 中加载 GML 文件并通过 WFS 提供服务

xml - XSD 架构目标命名空间