我正在将netty中的数据发送到统一3d游戏引擎中的c#应用程序,其中它读取数据包ID并根据数据包ID(在线程内)执行不同的方法,BinaryReader读取的数据包ID错误且我无法理解为什么
这里是类custombuffer,datainputstream,dataoutputstream:https://docs.google.com/document/d/1LmW8fzGFFnkgqV_kS-TnBi7XvVYTC4Q4kHWJT60UF00/edit?usp=sharing
你没有仔细阅读它们我发布它们以便你知道它们是什么
这是登录方法
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;
}
}
}
在登录后,其处理的perfectrly服务器发送带有数据包ID 2的字符创建结果,当它到达客户端时,它首先运行packetsIn.Login()
(这是0的packetid)和writeInt(2)来自SendCharacterCreationResult
从下面的方法中获取,其中byte opcode = ClientInput.ReadByte();
等于(2)我尝试了这样的int opcode = clientInput.ReadInt();它给出了相同的结果。如果我困惑你告诉我在文本中添加完整的文件
这是inputloop(在线程中运行)中的case 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,我无法理解为什么
答案 0 :(得分:0)
在PacketEncoder#SendCharacterCreationResult
中,您通过网络发送三个变量
out.writeInt(2);
out.writeBoolean(exists);
out.writeBoolean(success);
确保无论您在何处阅读所有三个变量的数据,您似乎仍在使用我已弃用的数据包系统,而这个数据库系统确实需要更换(您将在本系列的后续版本中找到它) ,来到第11部分)
您无法提供客户端收到数据包ID为2时处理的代码,但您看到的结果是由于TCP流中存在剩余数据。
在不推荐使用的系统中,您通过客户端发送的第一件事是整数(32位),客户端将其解释为数据包标识号(或操作码)。在你周围某个地方的视频中,我们改变了将数据包标头从字节(8位)读取到Int(32位)的方式,确保在读取数据包id(操作码)时客户端你正在读取整数而不是字节。
EDIT: I see that you already did this, didn't notice the posted code
完成上述操作后,请在收到Opcode of 2时调用您正在调用的任何方法,然后确保从PacketsIn#CharacterCreate
正确读取所有数据。发出两个DataInputStream#ReadBoolean()
来电。 (注意: DataInputStream实例在您的应用程序中称为 ClientInput )。
在您发布PacketsIn#CharacterCreate()
代码之前,我无法继续提供帮助。
答案 1 :(得分:0)
终于我明白了!问题出在PacketDecoder#Login()
方法中,当登录成功时它正在读取服务器发送的一个int,所以我做了什么,我把这两行代码放在&#34;别的&#34;条件
此代码位于Login()
byte opcode = ClientInput.ReadByte ();
Debug.Log( GetLoginMessage (opcode) );
}
这是有效的,因为如果值为false,服务器会发送opcode
一切正常!也许你应该通知别人,因为我检查了视频,你在其他情况之外就像我一样得到它