gpt4 book ai didi

c# - 关于 C# 中 RCON 协议(protocol)实现的令人难以置信的问题

转载 作者:行者123 更新时间:2023-11-30 12:16:12 46 4
gpt4 key购买 nike

我再次需要你的帮助来解决我的这个问题......已经一天了,我似乎无法找出为什么我的代码和输出会发生这种情况。

好的.....所以基本上我正在尝试实现 RCON Protocol C# 中的 Valve,到目前为止我得到了 expected output给出以下代码和示例用法:

用法:

RconExec(socket, "cvarlist");

代码:

private string RconExec(Socket sock, string command)
{
if (!sock.Connected) throw new Exception("Not connected");

//sock.DontFragment = true;
sock.ReceiveTimeout = 10000;
sock.SendTimeout = 10000;
//sock.Blocking = true;

Debug.WriteLine("Executing RCON Command: " + command);

byte[] rconCmdPacket = GetRconCmdPacket(command);
sock.Send(rconCmdPacket); //Send the request packet
sock.Send(GetRconCmdPacket("echo END")); //This is the last response to be received from the server to indicate the end of receiving process
RconPacket rconCmdResponsePacket = null;

string data = null;

StringBuilder cmdResponse = new StringBuilder();

RconPacket packet = null;
int totalBytesRead = 0;

do
{
byte[] buffer = new byte[4]; //Allocate buffer for the packet size field
int bytesReceived = sock.Receive(buffer); //Read the first 4 bytes to determine the packet size
int packetSize = BitConverter.ToInt32(buffer, 0); //Get the packet size

//Now proceed with the rest of the data
byte[] responseBuffer = new byte[packetSize];

//Receive more data from server
int bytesRead = sock.Receive(responseBuffer);

//Parse the packet by wrapping under RconPacket class
packet = new RconPacket(responseBuffer);
totalBytesRead += packet.String1.Length;

string response = packet.String1;
cmdResponse.Append(packet.String1);

Debug.WriteLine(response);

Thread.Sleep(50);

} while (!packet.String1.Substring(0,3).Equals("END"));

Debug.WriteLine("DONE..Exited the Loop");
Debug.WriteLine("Bytes Read: " + totalBytesRead + ", Buffer Length: " + cmdResponse.Length);

sock.Disconnect(true);

return "";
}

问题:

这还不是最终代码,因为我只是在调试窗口中测试输出。如果我将代码修改为实际状态,则会出现几个问题。

  1. 删除 Thread.Sleep(50)

    • 如果我删除 Thread.Sleep(50),输出不会完成并最终引发异常。我注意到服务器过早发送了“END”终止字符串。此字符串应仅在整个列表完成时由服务器发送。 Exception Thrown我对此进行了多次测试,同样的事情发生了,如果我不删除该行,列表就会完成并且函数会正确退出循环。
  2. 在循环内删除 Debug.WriteLine(response); 并在循环外使用 Debug.WriteLine(cmdResponse.ToString()); 输出字符串, 仅显示部分列表数据。如果我将从循环中读取的实际字节数与 StringBuilder 实例的长度进行比较,它们是否相同?点击here对于生成的输出。

为什么会出现上述两种情况?

最佳答案

您没有考虑到 Socket.Receive 读取的字节数可能少于所提供缓冲区的长度。返回值告诉您实际读取的字节数。我看到您正确地将此值存储在变量中,但我看不到任何使用它的代码。

您应该准备多次调用 Receive 以检索整个包。特别是当您收到包裹数据时。

我不确定这是否是您遇到问题的原因。但它可能是,因为客户端的短暂延迟可能足以填满网络缓冲区,以便在一次调用中读取整个包。

尝试使用以下代码检索包数据:

int bufferPos = 0;
while (bufferPos < responseBuffer.Length)
{
bufferPos += socket.Receive(responseBuffer, bufferPos, responseBuffer.Length - bufferPos, SocketFlags.None);
}

注意:您还应该支持第一次调用 Receive(接收包的数据长度的调用)不返回 4 个字节的情况。

关于c# - 关于 C# 中 RCON 协议(protocol)实现的令人难以置信的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5869498/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com