以下是代码:
System.out.println("[Server] Handshake Recieved");
String fdata = new String(p.getData());
String[] data = fdata.split(";");
System.out.println(fdata);
System.out.println(data.length);
System.out.println(data[0]);
p是我制作的Packet类的名称。 getData()返回一个我可以确认总是正确返回的字节数组。
当此代码与data [0]一起运行时,这是控制台输出:
CID;0;Username;Dummy
4
CID
但是当我用数据[1]运行它时,会发生这种情况:
<blank>
1
Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: 1
at server.S_GameLoop.parseData(S_GameLoop.java:122)
at server.S_GameLoop.Update(S_GameLoop.java:87)
at server.S_GameLoop.Running(S_GameLoop.java:66)
at server.S_GameLoop.run(S_GameLoop.java:157)
at java.lang.Thread.run(Thread.java:724)
我不知道为什么会这样。也许你们其中一个人知道答案?
编辑: 这是包含有问题代码的函数:
private void parseData(Packet p, DatagramPacket recievePacket) throws IOException, MethodNotOverridenException {
switch (p.getTagAsString()) {
case "LGN_RQS":
System.out.println("[Server] Login Request Recieved");
//Login was accepted
//Create a Client ref, and add it to the vector
S_Client newClient = new S_Client(recievePacket.getAddress(), recievePacket.getPort());
ClientList.add(newClient);
//Create a player and add it to Entity list
Player newPlayer = new Player(IDGenerator.getAndIncrement(), ClientList.indexOf(newClient));
EntityMap.put(newPlayer.getEntID(), newPlayer);
System.out.println("[Server] Created new Player with EID " + newPlayer.getEntID() + " and CID " + newPlayer.getCID());
//Send reply to Client that is logging in
sendData(new Packet((byte)2, "LGN_ACP".toCharArray(), ("CID;" + ClientList.indexOf(newClient) + ";EID;" + newPlayer.getEntID()).getBytes()).getBytes(), newClient.getIp(), newClient.getPort());
//New Entity was created
sendData(newPlayer.onCreate(this));
case "HND_SHK":
System.out.println("[Server] Handshake Recieved");
String fdata = new String(p.getData());
String[] data = fdata.split(";");
System.out.println(p.getData()); //[B@170ad4d5
System.out.println(fdata);
System.out.println(data.length);
System.out.println(data[0]);
/*S_Client c = ClientList.get(Integer.parseInt(data[1]));
c.setUsername(data[3]);
System.out.println("[Server] Set Client " + data[1] + "'s user to " + data[3]); */
}
}
这是Packet.java:
public class Packet {
private byte ID;
private char[] Tag;
private byte[] Data;
public Packet(byte ID, char Tag[]) {
this.ID = ID;
if(Tag.length <= 7)
this.Tag = Tag;
else
throw new IllegalArgumentException("Tag must be at most 7 characters long");
this.Data = new byte[1];
}
public Packet(byte ID, char Tag[], byte[] Data) {
this.ID = ID;
if(Tag.length <= 7)
this.Tag = Tag;
else
throw new IllegalArgumentException("Tag must be at most 7 characters long");
this.Data = Data;
}
/*
* Returns the packet ID
*/
public byte getID() {
return ID;
}
/*
* Return's the packet TAG
*/
public char[] getTag() {
return Tag;
}
public String getTagAsString() {
return new String(Tag);
}
public byte[] getData() {
return Data;
}
public byte[] getBytes() {
byte[] c = {ID};
return concat(c, concat(new String(Tag).getBytes(), Data));
}
public byte[] concat(byte[] A, byte[] B) {
int aLen = A.length;
int bLen = B.length;
byte[] C= new byte[aLen+bLen];
System.arraycopy(A, 0, C, 0, aLen);
System.arraycopy(B, 0, C, aLen, bLen);
return C;
}
}
第二次修改:
一点澄清。我运行程序两次。一次使用数据[0],一次使用数据[1]。每次我运行它。它们都产生完全相同的个体结果。 data [0]将始终返回
CID;0;Username;Dummy
4
CID
哪个是对的。但是,使用数据[1]交换数据[0]将始终返回
**<blank>
1**
Exception in thread "Thread-0" java.lang.ArrayIndexOutOfBoundsException: 1
at server.S_GameLoop.parseData(S_GameLoop.java:122)
at server.S_GameLoop.Update(S_GameLoop.java:87)
at server.S_GameLoop.Running(S_GameLoop.java:66)
at server.S_GameLoop.run(S_GameLoop.java:157)
at java.lang.Thread.run(Thread.java:724)
最终修改
如果有人以某种方式遇到这个问题。问题是我伪造在我的switch语句中添加break;
。
答案 0 :(得分:3)
仔细查看第二个日志输出。在程序的第二次运行中,fdata String为空,因此第一行是<blank>
。当您使用';'标记空白字符串时,您将获得一个标记,也是一个空字符串。因此,日志的第2行为1(令牌数组中包含1个元素)。然后尝试索引索引1处的令牌数组(它访问数组的SECOND元素);索引0中只有一个元素,因为数组的长度为1.因此,如异常所示,您的索引超出范围。
看起来程序中的真正错误是p.getData()有时会返回一个空字符串。这表明你的“确认[数据包]总是正确返回”的逻辑有一个错误。
答案 1 :(得分:2)
很明显。您的不同测试确实使用了从p.getData()
收到的不同数据。
在第一次测试时,您的方法p.getData()
返回一个好的String来处理。第二个测试,你有一个空字符串(大小为0),这不是你所期望的。因此,请查看您提供的代码,并搜索p.getData()
确实返回不同内容的原因。
答案 2 :(得分:-1)
您的数组只有一个元素,很可能是因为split会删除尾随的空字符串(如果有的话)。 array[1]
尝试访问不存在的第二个元素。