Java 为什么BinaryReader在线程内,从netty读取错误的数据包?
我将数据从netty发送到unity 3d游戏引擎中的一个c应用程序,在那里它读取数据包id并根据线程中的数据包id执行不同的方法,BinaryReader读取的数据包id是错误的,我无法理解为什么 以下是custombuffer、datainputstream和dataoutputstream的类: 你不必仔细阅读,我把它们贴在网上,这样你就知道它们是什么了 这是登录方法Java 为什么BinaryReader在线程内,从netty读取错误的数据包?,java,c#,sockets,unity3d,netty,Java,C#,Sockets,Unity3d,Netty,我将数据从netty发送到unity 3d游戏引擎中的一个c应用程序,在那里它读取数据包id并根据线程中的数据包id执行不同的方法,BinaryReader读取的数据包id是错误的,我无法理解为什么 以下是custombuffer、datainputstream和dataoutputstream的类: 你不必仔细阅读,我把它们贴在网上,这样你就知道它们是什么了 这是登录方法 public void SendLogin(string username,string password) {
public void SendLogin(string username,string password)
{
Debug.Log ("Sending username and password");
CustomBuffer buffer = new CustomBuffer (ClientOutput);
buffer.WriteUTF (username);
buffer.WriteUTF (password);
buffer.SendBuffer ();
}
下面是sendLogin的服务器处理程序
public PacketEncoder sendLogin(boolean value, Account account,byte opcode) {
ChannelBuffer buffer = new DynamicChannelBuffer(2);
ChannelBufferOutputStream out = new ChannelBufferOutputStream(buffer);
try {
out.writeInt(0);
out.writeBoolean(value);
System.out.println("sendig login back packet 0");
if(value) {
System.out.println("value true sending username");
out.writeUTF(account.getUsername());
}
else if(!value) {
System.out.println("value false sending opcode : "+ String.valueOf( (int)opcode));
out.writeByte(opcode);
}
Send(out.buffer());
out.close();
} catch(IOException e) {
e.printStackTrace();
}
return this;
}
在这里它工作正常!下面是问题
这是在角色创建请求后发送回信息的netty方法
public PacketEncoder SendCharacterCreationResult(boolean exists,boolean success) {
ChannelBuffer buffer = new DynamicChannelBuffer(2);
ChannelBufferOutputStream out = new ChannelBufferOutputStream(buffer);
try {
out.writeInt(2);
out.writeBoolean(exists);
out.writeBoolean(success);
//debug console
System.out.println(" ");
System.out.println("Sending Character Creation Result packet : 2");
System.out.println("exists : " + String.valueOf(exists));
System.out.println("success : " + String.valueOf(success));
Send(out.buffer());
out.close();
} catch(IOException e)
{
e.printStackTrace();
}
return this;
}
这是来自c的数据包处理程序
void InputLoop()
{
while(Client.Connected)
{
int packetID = ClientInput.ReadInt();
Debug.Log("packedID : " + packetID);
switch(packetID)
{
case 0: //Login
PacketsIn.Login();
break;
case 1://Character Request Response
PacketsIn.CharacterRequest();
break;
case 2: //Character Creation Response
PacketsIn.CharacterCreate();
break;
}
}
}
登录后,其Perfectly服务器发送数据包id为2的字符创建结果,当它首先到达客户端时,它将运行packetsIn.login,即数据包id为0的数据包和SendCharacterCreationResult中的writeInt2
从下面的方法读取,其中byte opcode=ClientInput.ReadByte;
等于2,我像这样尝试int-opcode=clientInput.ReadInt;它给出了同样的结果。如果我把你搞糊涂了,告诉我在文本中添加完整的文件
这是在线程中运行的inputloop中案例0的函数
public void Login()
{
bool success = ClientInput.ReadBoolean ();
if(success)
{
string username = ClientInput.ReadUTF();
Debug.Log("Successfuly Logged In. " + username);
MasterClient.singleton.ChangeScene(4);
}
byte opcode = ClientInput.ReadByte ();
//GameObject.Find ("MessageLogsText").GetComponent<UILabel> ().text
Debug.Log( GetLoginMessage (opcode) );
}
private string GetLoginMessage(byte opcode)
{
switch(opcode)
{
case 0:
return "Invalid Usarename Or Password";
case 1:
return "Account Is Already Logged In";
case 2:
return "test";
default:
return "Invalid opcode Sent From Server";
}
}
然后数据包id变为513,我无法理解为什么在PacketEncoderSendCharacterCreationResult中,您通过网络发送三个变量
out.writeInt(2);
out.writeBoolean(exists);
out.writeBoolean(success);
确保无论您在哪里读取数据,您都在读取所有三个变量,看起来您仍然在使用我不推荐的数据包系统,这确实需要更换。您将在本系列后面的第11部分中看到
您未能提供当客户端接收到两个数据包id时处理的代码,但您看到的结果是由于TCP流中存在剩余数据
在不推荐使用的系统中,通过客户机发送的第一件事情是整数32位,客户机将其解释为数据包标识号或操作码。在您当前位置周围的某个视频中,我们将数据包头从字节8位读取的方式更改为Int32位。请确保在客户端上读取数据包idopcode时读取的是整数而不是字节
编辑:我看到你已经这样做了,没有注意到张贴的代码
完成此操作后,在收到2的操作码时,进入正在调用的任何方法,然后确保正确地从PacketsInCharacterCreate读取所有数据。您需要发出两个DataInputStreamReadBoolean调用。注意:DataInputStream实例在应用程序中称为ClientInput
在你发布PacketsInCharacterCreate的代码之前,我再也帮不了你了 我终于明白了!问题出在PacketDecoderLogin方法中,当登录成功时,它正在读取服务器未发送的int,所以我所做的是,将这两行代码置于else条件下 此代码在登录中 字节操作码=ClientInput.ReadByte; Log GetLoginMessage操作码; } 这是因为如果值为false,服务器将发送操作码
一切都很好!也许你应该通知其他人,因为我检查了视频,你像我一样在其他条件之外得到了它没有看到接收数据的实际代码,甚至无法开始评论可能的错误。但是你的第一步是调试更多的问题;你需要做更多的研究,包括从传输到最终接收的每一步都要检查数据,这样你就可以首先准确地知道数据被误解的地方。我敢打赌你肯定在某个地方遇到了字节排序问题,但这只是一个猜测。看,嘿,彼得,我的英语不是很好,我尽了最大的努力…我将尝试编辑它并添加更多的内容。此外,我想评论一下,彼得·杜尼霍也是正确的,但这不是目前影响应用程序的因素。我会知道的,因为我写了原始教程。但是,您正在使用的DataInputStream版本已弃用,应予以替换。教程系列第11部分中的下载链接我没有提供CharacterCreate,因为InputLoop不运行调用CharacterCreate的案例2,而是运行案例0,该案例0是包含int-opcode=ClientInput.ReadInt的登录名,并且操作码变为2,因此线程有问题,这2应该由InputLoop的int packetID=ClientInput.ReadInt;读取。如果您未通知,我在clientINput.ReadInt之后有Debug.LogpacketID;它是在操作码的Debug.Log之后执行的,它会打印出513号,我不知道它们是如何无序执行的,这甚至是不可能的,甚至没有注意到在你的代码中,但是的,这会把所有的东西都抛出循环。