[Twisted-Python] UDP with multiple connections
Ok, UDP is new to me, so please be gentle.... I've got a server authentication app which needs to accept many client connections, but also dispatch messages to a master server. Am I best using unconnected UDP? do i then have to deal with each received datagram by checking which host is has come from and acting accordingly? thanks Simon
On Tue, 2007-10-09 at 21:21 +0100, Simon Pickles wrote:
Ok, UDP is new to me, so please be gentle....
I've got a server authentication app which needs to accept many client connections, but also dispatch messages to a master server. Am I best using unconnected UDP?
You are *best* using TCP. Very few applications are actually suited to UDP. UDP: * has no connection state * has no flow control * is unfriendly to networks (really the same as the previous point) * has no keepalives * has problems with MTU and fragmentation for messages > ~1400 bytes * is subject to trivial spoofing * has no message sequencing * is hard to run crypto over (SSL over TCP == trivial) ...and so on.
do i then have to deal with each received datagram by checking which host is has come from and acting accordingly?
Twisted's UDP support is all "unconnected". All DatagramProtocol instances get a call to: def datagramReceived(self, data, addr) ...where "addr=(ip,port)" for IPv4 Similarly, you would do: self.transport.write(bytes, addr) So, unconnected UDP is your *only* option, because that's how Twisted does it. However, so-called "connected" UDP is really just a way of saving the destination address on the socket. There's no *actual* connection involved.
thanks
Simon
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
On Wed, 10 Oct 2007 00:37:02 +0100, Phil Mayers <p.mayers@imperial.ac.uk> wrote:
On Tue, 2007-10-09 at 21:21 +0100, Simon Pickles wrote:
Ok, UDP is new to me, so please be gentle....
I've got a server authentication app which needs to accept many client connections, but also dispatch messages to a master server. Am I best using unconnected UDP?
You are *best* using TCP. Very few applications are actually suited to UDP. UDP:
* has no connection state * has no flow control * is unfriendly to networks (really the same as the previous point) * has no keepalives * has problems with MTU and fragmentation for messages > ~1400 bytes * is subject to trivial spoofing * has no message sequencing * is hard to run crypto over (SSL over TCP == trivial)
...and so on.
do i then have to deal with each received datagram by checking which host is has come from and acting accordingly?
Twisted's UDP support is all "unconnected". All DatagramProtocol instances get a call to:
def datagramReceived(self, data, addr)
...where "addr=(ip,port)" for IPv4
Similarly, you would do:
self.transport.write(bytes, addr)
So, unconnected UDP is your *only* option, because that's how Twisted does it.
However, so-called "connected" UDP is really just a way of saving the destination address on the socket. There's no *actual* connection involved.
Everything else here is right, but one correction: Twisted does support "connected" UDP, via IUDPTransport.connect(). This is indeed little more than a convenience API, though. You get to skip passing the address argument to transport.write() if you use it, and you _may_ receive connectionFailed notification (which, for example, tells you if you are sending packets to a port where no application is listening for them), if all the involved routers decide to cooperate (they frequently will not). Jean-Paul
UDP is often used in online gaming, where other methods are employed to compensate for its weaknesses, in return for its speed. Phil Mayers wrote:
On Tue, 2007-10-09 at 21:21 +0100, Simon Pickles wrote:
Ok, UDP is new to me, so please be gentle....
I've got a server authentication app which needs to accept many client connections, but also dispatch messages to a master server. Am I best using unconnected UDP?
You are *best* using TCP. Very few applications are actually suited to UDP. UDP:
* has no connection state * has no flow control * is unfriendly to networks (really the same as the previous point) * has no keepalives * has problems with MTU and fragmentation for messages > ~1400 bytes * is subject to trivial spoofing * has no message sequencing * is hard to run crypto over (SSL over TCP == trivial)
...and so on.
do i then have to deal with each received datagram by checking which host is has come from and acting accordingly?
Twisted's UDP support is all "unconnected". All DatagramProtocol instances get a call to:
def datagramReceived(self, data, addr)
...where "addr=(ip,port)" for IPv4
Similarly, you would do:
self.transport.write(bytes, addr)
So, unconnected UDP is your *only* option, because that's how Twisted does it.
However, so-called "connected" UDP is really just a way of saving the destination address on the socket. There's no *actual* connection involved.
thanks
Simon
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
Thanks for the advice. My dilemma continues. In my game server, I firstly tried an approach like divmod suggests, using TCP for 'slow' operations like authentication, chat. Then I tried to run a separate UDP thread doing 'fast' ops like position updates. However I stumbled when the reactor didn't like not being in the main thread (it was the second reactor in the app) I've come to a new design now, where the server structure is split into: auth, chat, generator, etc, plus a master 'conductor' - TCP using python+twisted game zone servers - C++/UDP Using UDP for the game server is strongly recommended by my industry contacts. Phil Mayers wrote:
On Thu, 2007-10-11 at 16:20 +0100, Simon Pickles wrote:
UDP is often used in online gaming, where other methods are employed to compensate for its weaknesses, in return for its speed.
I am aware of this. What's your point?
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python </
On Thu, 11 Oct 2007 19:24:02 +0100, Simon Pickles <sipickles@hotmail.com> wrote:
[snip]
Hi, http://twistedmatrix.com/projects/core/documentation/howto/servers.html Hope this helps, Jean-Paul
My problem is my app needs to be a server to many clients (thru TCP - twisted.protocols.basic) but a client to a further server, to which it passes occasional information. Is this possible through twisted, since I need two threads, one with the server reactor.run() and one with the client connection listenTCP()? At present using UDP for the client connection, if I call reactor.run() after listenUDP(), I get: Traceback (most recent call last): File "E:\Dev\Python\Lib\threading.py", line 460, in __bootstrap self.run() File "G:\_Dev\Gateway 20071011\gatewayClient.py", line 59, in run reactor.run() File "E:\Dev\Python\lib\site-packages\twisted\internet\posixbase.py", line 219, in run self.startRunning(installSignalHandlers=installSignalHandlers) File "E:\Dev\Python\lib\site-packages\twisted\internet\posixbase.py", line 215, in startRunning self._handleSignals() File "E:\Dev\Python\lib\site-packages\twisted\internet\posixbase.py", line 185, in _handleSignals signal.signal(signal.SIGTERM, self.sigTerm) ValueError: signal only works in main thread If I don't call reactor.run(), it works. I can still send and recieve. What then, is the role of the reactor? I thought it started the listening loop? Thanks Simon Jean-Paul Calderone wrote:
On Thu, 11 Oct 2007 19:24:02 +0100, Simon Pickles <sipickles@hotmail.com> wrote:
[snip]
Hi,
http://twistedmatrix.com/projects/core/documentation/howto/servers.html
Hope this helps,
Jean-Paul
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python
On 10/11/07, Simon Pickles <sipickles@hotmail.com> wrote:
My problem is my app needs to be a server to many clients (thru TCP - twisted.protocols.basic) but a client to a further server, to which it passes occasional information.
Is this possible through twisted, since I need two threads, one with the server reactor.run() and one with the client connection listenTCP()?
No you don't! listenTCP does not block. You can have as many connections as you want in a single reactor. Twisted is an *asynchronous* networking framework. You don't need multiple threads for this use case. -- Christopher Armstrong International Man of Twistery http://radix.twistedmatrix.com/ http://twistedmatrix.com/ http://canonical.com/
On 08:04 pm, radix@twistedmatrix.com wrote:
On 10/11/07, Simon Pickles <sipickles@hotmail.com> wrote:
My problem is my app needs to be a server to many clients (thru TCP - twisted.protocols.basic) but a client to a further server, to which it passes occasional information.
Is this possible through twisted, since I need two threads, one with the server reactor.run() and one with the client connection listenTCP()?
No you don't!
listenTCP does not block. You can have as many connections as you want in a single reactor. Twisted is an *asynchronous* networking framework. You don't need multiple threads for this use case.
Please allow me to emphasize. This is an important point. Call listenTCP. Then, immediately call listenUDP. Then you will have a TCP server and a UDP server. When TCP connections arrive, they will be connected using buildProtocol on your factory. When UDP packets arrive, they will be delivered to datagramReceived on your UDP protocol. You can then deliver those packets to whatever code you need to, whether it's C++ or Python or whatever. You do not need, and should not want, threads for multiple sources of I/O. If you want to take advantage of multiple cores or something, you can always run your C++ code that responds to some events in a separate process (or thread, if you are so inclined). I would, however, suggest that you implement _all_ your messages using TCP over a single connection at first. Once you have really understood and internalized the event-driven nature of Twisted, and implemented all the code needed to respond to position updates and so on, you will be able to easily split out the code that receives and parses those updates into a separate UDP class. This will force you to deal with the fact that there is no deep architectural difference between delivering some messages over TCP and others over UDP. If you instead start off with a two-protocol design that you do not entirely understand, your game's network architecture will be the result of a series of misunderstandings, not a well-planned whole. Using UDP for position updates is simply an optimization, and one that you can make fairly late in development. All the code to process and respond to them *should* be unchanged, regardless of how they are delivered. Testing on local networks and fast links should be unaffected at first: UDP's performance advantage only comes into play when packets are being dropped, so it's only going to affect your game over long-haul links or really slow local networks.
On 03:20 pm, sipickles@hotmail.com wrote:
UDP is often used in online gaming, where other methods are employed to compensate for its weaknesses, in return for its speed.
"Speed" is an oversimplified way of explaining this usage. Some games use a TCP control channel for most logical messages and UDP for updates to a small set of values where only the _most current_ value ever matters. This is most often the position, orientation, and velocity of an object in the game world. This can improve the apparent performance of twitchy games over lossy links. Some games, having heard secondhand about this previous strategy, use UDP for everything because their implementors mistakenly believe that it's faster than TCP. Often, these games eventually switch to TCP later in the development cycle when networking bugs and profiling indicate that the features of TCP are actually required or the performance "gains" are actually losses. For example, routers on the public internet can and often do cheat in a variety of ways to use the additional information that TCP provides to make it go faster. UDP can't take advantage of that and its overall throughput is often slower (especially on congested networks).
I would like to make a general comment about the use of UDP in applications. There are some people on this list who can do some tricky things with UDP, but as a general rule, what should be recommended is "use TCP". If you end up running into issues that TCP has problems with, there are other options, but you should have tried TCP first. If you are asking advise on this forum on using UDP, the first reply should always be: "Why arn't you using TCP?", and the second reply should be "Have you actually tried TCP and seen problems with it?" UDP is fun and if you know what you are doing, you can get some benefits out of it, but you have to put an awful lot of work into it and I have seen many cases where the promised benefits of using UDP are not seen. Areas where UDP can give some benefits are: Overcoming latency due to a 3way handshake, reducing cost if you are charged by the byte (but this can be eaten up by development cost and retransmission), multicast (but you then need to have control over your network). I have heard of at least one case where large UDP applications have been put in due to the perceived benefits, only to be replaced by a TCP application that actually works. -- Carl zmola@acm.org
I thiank you all for your tiem and patience. My understanding has developed somewhat :) Carl Zmola wrote:
I would like to make a general comment about the use of UDP in applications. There are some people on this list who can do some tricky things with UDP, but as a general rule, what should be recommended is "use TCP". If you end up running into issues that TCP has problems with, there are other options, but you should have tried TCP first. If you are asking advise on this forum on using UDP, the first reply should always be: "Why arn't you using TCP?", and the second reply should be "Have you actually tried TCP and seen problems with it?"
UDP is fun and if you know what you are doing, you can get some benefits out of it, but you have to put an awful lot of work into it and I have seen many cases where the promised benefits of using UDP are not seen.
Areas where UDP can give some benefits are: Overcoming latency due to a 3way handshake, reducing cost if you are charged by the byte (but this can be eaten up by development cost and retransmission), multicast (but you then need to have control over your network).
I have heard of at least one case where large UDP applications have been put in due to the perceived benefits, only to be replaced by a TCP application that actually works.
-- Carl zmola@acm.org
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python </
On Thu, 2007-10-11 at 16:30 +0000, glyph@divmod.com wrote:
On 03:20 pm, sipickles@hotmail.com wrote:
UDP is often used in online gaming, where other methods are employed to compensate for its weaknesses, in return for its speed.
"Speed" is an oversimplified way of explaining this usage.
Some games use a TCP control channel for most logical messages and UDP for updates to a small set of values where only the _most current_ value ever matters. This is most often the position, orientation, and velocity of an object in the game world. This can improve the apparent performance of twitchy games over lossy links.
Some games, having heard secondhand about this previous strategy, use UDP for everything because their implementors mistakenly believe that it's faster than TCP. Often, these games eventually switch to TCP later in the development cycle when networking bugs and profiling indicate that the features of TCP are actually required or the performance "gains" are actually losses. For example, routers on the public internet can and often do cheat in a variety of ways to use the additional information that TCP provides to make it go faster. UDP can't take advantage of that and its overall throughput is often slower (especially on congested networks).
_______________________________________________ Twisted-Python mailing list Twisted-Python@twistedmatrix.com http://twistedmatrix.com/cgi-bin/mailman/listinfo/twisted-python -- George Pauly Ring Development www.ringdevelopment.com
participants (7)
-
Carl Zmola
-
Christopher Armstrong
-
George Pauly
-
glyph@divmod.com
-
Jean-Paul Calderone
-
Phil Mayers
-
Simon Pickles