1

AS3 の MMORPG 用に Java でソケット サーバーをプログラミングしています。HashMap.get(byte[]) の奇妙な動作に問題があります。次の問題の原因は何ですか?

私はシリアル化システムを使用しません。バイトを送信し、クライアントとサーバーの両方が、受信したバイトのどのバイトをどう処理するかを知っています。クライアントが行う最初の要求は、再生セッションを作成するようサーバーに要求することです。サーバーは、8 つのエントリを持つ byte[] としてランダムなセッション トークンを生成し、トークンを HashMap に追加します。応答の長さは 9 バイトです。最初のものは応答タイプを定義し (この場合、バイト '+' は「受け入れられました。これがトークンです」を意味します)、バイト 2 から 9 はトークンです。クライアントはトークンを保存し、それを以降のリクエストに追加する必要があります (この概念は PHP セッションと比較できます)。

これは、クライアントを HashMap に追加するためのコードです。

byte[] token = Util.generateToken();

// f is ResultSet entry of JDCB SQL query return value
Client client = new Client(f.getInt("id"), token);
Core.clients.put(token, client);

// I display client.token instead of token to make sure client != null      
Log.log("User " + f.getString("name") + " has logged in with session token " + Util.getHexString(client.token) + ".");

ログ:

[01:50:30] ユーザーがセッション トークン 92:B7:F8:C6:4B:53:17:3A でログインしました。

これらは、以降の要求で表示されるいくつかのデバッグ行です。

// Show (byte[]) Token as Hex String, 8 bytes long
Log.soc("Token: " + Util.getHexString(buffer.getBytes(1, 9)));

// Show all keys in (HashMap<byte[], client>) Core.clients
int it = 0;
for (byte[] b : Core.clients.keySet())
Log.soc("Key Core.clients #" + StringUtils.leftPad(String.valueOf(++it), 2, '0') + " = " + Util.getHexString((b)));

// Display availability bool to make sure
Log.soc(Core.clients.containsKey(buffer.getBytes(1, 9)));

// Get Core.clients value where key = Token
Log.soc("Client: " + Core.clients.get(buffer.getBytes(1, 9)));

ログ:

[01:51:09] トークン: 92:B7:F8:C6:4B:53:17:3A

[01:51:09] キー Core.clients #01 = 92:B7:F8:C6:4B:53:17:3A

[01:51:09] 偽

[01:51:09] クライアント: null

では、どうすれば何が問題なのかを知ることができますか?

4

1 に答える 1

8

HashMap はhashCode()とを使用しequals()て、特定のキーからエントリを検索します。また、バイト配列はそれ自体とのみ等しくなります。この他のバイト配列が同じ長さと同じバイトを持っていたとしても、それは別のバイト配列と等しくなりません。equals()オーバーライドして機能させるには、配列を Key クラス内にラップする必要がありますhashCode()

于 2013-01-27T22:38:46.377 に答える