[bf1942] Using sqlite with BF2 in Windows

Andreas Fredriksson deplinenoise at gmail.com
Fri Apr 21 11:01:27 EDT 2006

On 4/21/06, "Einar S. Idsø" <esi at itk.ntnu.no> wrote:

> My plan was to have a UDP listen socket bound to a specific port on the
> game server. The servermanager will also have a UDP socket bound to a
> specific port. The server and the manager will both act as clients and
> servers to each other: Whenever the server needs to communicate with the
> servermanager, it will fire off a UDP packet and not wait for a
> response. The servermanager then handles the request and sends the
> response back to the server on its bound UDP port. Is this what you
> mean, or can it be made more elegant, yet still asynchronous? Would TCP
> be a better option for this? Any suggestions you as the implementor of
> the Python-engine may have, will be very highly appreciated.

Using UDP this way has two serious drawbacks: fixed upper message
length and non-guaranteed delivery. UDP on localhost isn't watertight
on the NT kernel, the per-process buffers are fairly small, if memory
serves. If you happen to trigger a cascade of packets within one
timeslice of your sender process, you could end up losing a great deal
of them because the other process hasn't got a chance to drain the
packet pool until it's scheduled again. Linux is much better.

This is why the BF engines have a separate high-priority thread that
exists only to empty the UDP buffers on windows, or we would see
dramatic packet loss on a busy single-CPU server (again because of
timeslicing vs UDP packet window size).

TCP on the other hand is tricky to use correctly in non-blocking mode.
However, if you're anticipating a low number of connections (as I did
in the RCON module), just go ahead and poll the socket now and then
for traffic. You can't use select(), because that would block the
server's main thread and stall gameplay as well. Writing works
similarily, you need to chop up outgoing data and maintain a write
cursor for each "packet", so that you can try to make progress with a
write and update the cursor as soon as there is work to be done.

I'd definitely go for a multiplexing TCP solution (similar to RCON)
because of the problems with UDP. If something breaks with TCP, at
least you know about it. Also, ordering can be very important in an
admin scenario (what if the ban request comes in after the kick
request, for instance).

> This is true for the 2.4 kernel, but for the 2.6 kernel it is 1ms, so a
> couple of context switches shouldn't cause much trouble, I hope. For
> Windows the default slice is 15.625ms, but this can easily be tweaked to
> 0.977ms.

I think the Fedora kernel uses a 200 HZ value, so it's still at 5 ms.
The point is that unless users are prepared to reconfigure their
systems, you can't rely on timeslicing or thread/process scheduling to
work in a certain way. Linux suffers even more from this because it's
not possible to change thread priorities from a non-root process (that
is, you can't boost an I/O thread for instance, this relates to the
nice() system call).

> Thanks a lot for your help, it is really appreciated! :)

No problem, I hope you work around these problems and build something
cool with it!

// Andreas

Those who live by the sword get shot by those who don't.

More information about the Bf1942 mailing list