Mental issue related to implementing RCON protocol in C #

Once again I need your help figuring out this problem ... It has been one day already and I cannot understand why this is happening in my code and output.

Ok ..... so basically I'm trying to implement RCON Protocol Valve in C #, while I get the expected result , given the use of the code and sample below:

Using:

RconExec(socket, "cvarlist"); 

Code:

 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 ""; } 

Problem:

This is not the final code, as I am just testing the output in the Debug window. There are several problems that arise if I modify the code for its actual state.

  • Thread.Sleep(50) Removal Thread.Sleep(50)

    • If I delete Thread.Sleep(50) , the output does not end and ends up throwing an exception. I noticed that the end line "END" is sent by the server ahead of schedule. It is expected that this line will be sent by the server only after the completion of the entire list. Exception thrown I have tested this many times, and the same thing happens if I do not delete the line, the list ends, and the function exits the loop properly.
  • Removing Debug.WriteLine(response); inside the loop and outputting a string using Debug.WriteLine(cmdResponse.ToString()); outside the loop, only partial list data is displayed. If I compare the actual bytes read from the loop with the length of the StringBuilder instance, are they the same? Click here for the generated result.

Why is this taking into account the two scenarios mentioned above?

+4
source share
1 answer

You do not think that Socket.Receive reads less bytes very well than the length of the provided buffer. The return value tells you the number of bytes that were actually read. I see that you correctly store this value in a variable, but I do not see any code that uses it.

You must be prepared to make several Receive calls to receive the entire packet. In particular, when you receive packet data.

I am not sure if this is the cause of your problem. But this may be so, since a short delay on the client side may be enough to fill the network buffers so that the entire packet is read in one call.

Try using the following code to extract package data:

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

Note. You should also support the case when the first Receive call (the one where you get the packet data length) does not return 4 bytes.

+3
source

All Articles