Talk:Source RCON Protocol: Difference between revisions

From Valve Developer Community
Jump to navigation Jump to search
Line 21: Line 21:
Ok, it seems a heuristic is necessary here. For a cvarlist I get 37 packets, and ignoring the last packet (3436 bytes), the split packets were between 3915 and 4103 bytes in size. The size is not constant because the output seems to be split by lines, instead of bytes... each packet starts with a cvar and ends with a \n. So I looked at the length of lines and they were between 0 and 201 characters. So for safety I will assume a maximum line length of about 400 characters (about two times the maximum of cvarlist) so if a packet is 3700 bytes or larger it will assume that another packet may follow. So my implementation will block and listen (until timeout) in this case, and otherwise just poll. This avoids unnecessary blocks for short responses or split responses that have a short last packet. If anyone has any better suggestions, please share.
Ok, it seems a heuristic is necessary here. For a cvarlist I get 37 packets, and ignoring the last packet (3436 bytes), the split packets were between 3915 and 4103 bytes in size. The size is not constant because the output seems to be split by lines, instead of bytes... each packet starts with a cvar and ends with a \n. So I looked at the length of lines and they were between 0 and 201 characters. So for safety I will assume a maximum line length of about 400 characters (about two times the maximum of cvarlist) so if a packet is 3700 bytes or larger it will assume that another packet may follow. So my implementation will block and listen (until timeout) in this case, and otherwise just poll. This avoids unnecessary blocks for short responses or split responses that have a short last packet. If anyone has any better suggestions, please share.
[[User:Frostschutz|Frostschutz]] 17:24, 26 January 2010 (UTC)
[[User:Frostschutz|Frostschutz]] 17:24, 26 January 2010 (UTC)
I found an alternative method that does not rely on heuristics, but it might be seen as a hack: Empty requests sent to the server, return an empty response. This means that if you send a (series of) request(s) to the server, you can follow it up with an empty request. This will act as a terminator: you know that you received the reply completely as soon as you receive the response to your terminator request. The downside of this is that it will add an additional entry to your server log (rcon from "1.2.3.4:5678": command "") and will add an overhead of 2 packets to every (series of) request(s).
Even if you decide to not use terminator packets, your implementation should be aware of changing request ids when sending a series of requests, so only the last request will have to wait for additional packets that will never come if the above heuristic fails.
[[User:Frostschutz|Frostschutz]] 13:04, 8 February 2010 (UTC)

Revision as of 06:04, 8 February 2010

This article was taken from a HLDS_APPS posting by Alfred Reynolds.

Additional Remarks have been added to Alfred's Documentation. This is taken from the KQuery Wiki (http://wikki.kquery.net/), as unfortunately the page is defaced. One can dig deeply through the revision history to obtain the information, some of which is vital to creating a working implementation.. I have taken the liberty of echoing it here. 20:51, 4 Feb 2006 - Erik Hollensbe

The C app (CLI / rcon.c) unfortunately does not work for me. I either get 'authentication failed' or 'Illegal size -559038737'. Maybe the app does not like 64bit Linux. Other apps (like SRCDS.py) work just fine but their code is hard to understand, and they require Python and the like. I googled for a better C implementation but couldn't come up with anything. Too bad there isn't a more official tool for this, as it can be really useful for maintaining servers remotely. Andreas Klauer 06:13, 14 Jul 2008 (PDT)

Packets splitting confusion

I have Ruby code able to receive really long RCON responses from Source servers. This works (even for cvarlist = 43 packets) almost flawlessly. But cvarlist (and maybe other requests) fails in around 1 of 4 tries. The problem is that the packet size of the split packets is wrong. It doesn't show the complete size of the packet, but only until the first zero-byte (0x00, the end of the first string component). In my experience the second string component isn't used very often, so the response is a string terminated by 2 zero-bytes in almost all cases. It's quite interesting that this error happens when the text of the response is split into the two strings. Even more interesting is that this happens always in the same section of the text (for cvarlist just in the middle of the description for ai_show_connect). In the moment I'm pretty sure this is a bug in Source as I can't imagine a purpose of this random behavior. --Koraktor 10:20, 8 Dec 2008 (PST)

I'd post that on hlcoders. --TomEdwards 10:47, 8 Dec 2008 (PST)
Already had that in mind. Thanks for the reminder. ;) --Koraktor 11:06, 8 Dec 2008 (PST)

How to receive split response?

How to receive a split response correctly? There's nothing that indicates that the packet is split, so currently I just continue listening for additional packets with the correct id and concatenate the string1 together until a timeout occurs. This works fine for cvarlist. I'm planning on optimizing this, by listening for additional packets only if the previous packet was long, i.e. if the probability for additional packets is high - this should work assuming that a split always means that the previous packets use the maximum length for string1 (4096 or something bytes according to the spec here). However this still means there is some chance I have to continue listening (and thus blocking the result) for nothing. Anyone know of a better way? Frostschutz 11:29, 26 January 2010 (UTC)

Ok, it seems a heuristic is necessary here. For a cvarlist I get 37 packets, and ignoring the last packet (3436 bytes), the split packets were between 3915 and 4103 bytes in size. The size is not constant because the output seems to be split by lines, instead of bytes... each packet starts with a cvar and ends with a \n. So I looked at the length of lines and they were between 0 and 201 characters. So for safety I will assume a maximum line length of about 400 characters (about two times the maximum of cvarlist) so if a packet is 3700 bytes or larger it will assume that another packet may follow. So my implementation will block and listen (until timeout) in this case, and otherwise just poll. This avoids unnecessary blocks for short responses or split responses that have a short last packet. If anyone has any better suggestions, please share. Frostschutz 17:24, 26 January 2010 (UTC)

I found an alternative method that does not rely on heuristics, but it might be seen as a hack: Empty requests sent to the server, return an empty response. This means that if you send a (series of) request(s) to the server, you can follow it up with an empty request. This will act as a terminator: you know that you received the reply completely as soon as you receive the response to your terminator request. The downside of this is that it will add an additional entry to your server log (rcon from "1.2.3.4:5678": command "") and will add an overhead of 2 packets to every (series of) request(s).

Even if you decide to not use terminator packets, your implementation should be aware of changing request ids when sending a series of requests, so only the last request will have to wait for additional packets that will never come if the above heuristic fails. Frostschutz 13:04, 8 February 2010 (UTC)