Hi, I thought about the problem last night and I came to the conclusion, that the sendto method actually does not make a problem for my scenario. I've implemented one of the most basic congestion avoidance stuff that TCP uses by default (slow start, congestion avoidance, bla bla) so if packets get dropped, I'll recognize this anyway. The nice thing about those congestion algorithms is, that it does not actually matter whether or not the sendto method blocks/succeeds. My prototype, which I finished early this morning does actually work(though it's far from perfect).
Of course the different behavior is annoying. Linux does this much better, even Windows, yark. Regarding RUDP: The speed of tcp is really hard to achieve, that's true. But it's not really about performance but about usability. TCP requires manual port forwarding when doing heavy p2p. With UDP you can do udp hole punching, which lets you through most of the NATs home users has. It's a bit like Skype used to be, well today it's going over Microsoft servers, but in the early days it uses exactly this technique to achieve this. My payload will most likely be text and a few photos, p2p. Am Montag, 24. Februar 2014 19:22:46 UTC+1 schrieb Guido van Rossum: > > Hm, so it sounds like the ENOBUFS error is intended as an improvement: it > at least tells the caller that the packet was dropped immediately, which is > a useful thing, even if the absence of that error does not constitute a > guarantee. Unfortunately it doesn't look like we can use this directly to > call pause_writing(), because there's no reliable way to tell that things > are going to work again, except by trying. > > Regarding "reliable" UDP, I guess if you're really implementing TCP on top > of UDP, you're not going to beat the performance of TCP. You're still going > to need all the same AKCs etc. But don't let me stop you, I'm sure you have > a good reason to do this. > > > On Mon, Feb 24, 2014 at 12:49 AM, Christopher Probst < > [email protected] <javascript:>> wrote: > >> This is from FreeBSD mailing lists, it definitely says that sendto does >> not block (select won't help, unfortunately it is like a file handle, it's >> always writable). >> >> http://lists.freebsd.org/pipermail/freebsd-hackers/2004-January/005369.html >> >> Well, I think it is safe to say that tulips Datagram control-flow will >> never really work on any BSD system. The sendto method simply never blocks. >> It's also easy to explain the behavior you get: One mail says that >> FreeBSD might drop packets, instead of raising ENOBUFS, so you get dramatic >> packet loss instead of an error. >> >> >> Am Montag, 24. Februar 2014 01:07:17 UTC+1 schrieb Guido van Rossum: >>> >>> "Reliable UDP"? Isn't that a contradiction? >>> >>> On Sunday, February 23, 2014, Christopher Probst < >>> [email protected]> wrote: >>> >>>> Thanks for your help so far, I really appreciate it. >>>> >>>> A manual backoff seems the best solution for this weird behavior for >>>> now, since reliable udp heavily depends on timing this is not such a bad >>>> thing anyway. >>>> >>>> Meanwhile I try to figure out the cause for this issue. >>>> >>>> >>>> Am Montag, 24. Februar 2014 00:31:24 UTC+1 schrieb Guido van Rossum: >>>>> >>>>> I still can't repro it with your code. But that doesn't mean it's not >>>>> a real condition. It sounds like the kind of odd corner of entirely >>>>> legitimate UDP behavior that is hard to provoke but which a robust app >>>>> should handle. >>>>> >>>>> Note that the default behavior in Tulip appears to be to ignore >>>>> OSError coming out of sendto() -- the transport calls >>>>> protocol.error_received(), which by default does nothing. Since there are >>>>> many other cases where a packet may silently be dropped on the floor, >>>>> this >>>>> behavior is technically correct -- the question is whether it is the best >>>>> default behavior we can imagine. >>>>> >>>>> Unfortunately turning it into a pause_protocol() call in your >>>>> error_received() handler is a little tricky -- the transport remembers >>>>> whether it has paused the protocol or not, but this state is not public. >>>>> So >>>>> you shouldn't call your own pause_writing(), since you'd never receive a >>>>> resume_writing() call from the transport. Perhaps you can set a flag >>>>> internal to your protocol that just causes you to back off for a brief >>>>> period of time? The optimal back-off time should be tuned experimentally. >>>>> >>>>> --Guido >>>>> >>>>> On Sun, Feb 23, 2014 at 2:45 PM, Christopher Probst < >>>>> [email protected]> wrote: >>>>> >>>>> I made a simpler test, without using tulip, just using plain >>>>> sockets<http://stackoverflow.com/questions/21973661/os-x-udp-send-error-55-no-buffer-space-available/21973705?noredirect=1#comment33297277_21973705> >>>>> . >>>>> >>>>> from socket import * >>>>> >>>>> udp = socket(AF_INET, SOCK_DGRAM) >>>>> udp.setsockopt(SOL_SOCKET, SO_REUSEADDR, True) >>>>> >>>>> udp.bind(('0.0.0.0', 1337)) >>>>> udp.setblocking(False) >>>>> udp.setsockopt(SOL_IP, IP_TTL, 4) >>>>> udp.connect(('8.8.8.8 >>>>> >>>>> >>> >>> -- >>> --Guido van Rossum (on iPad) >>> >> > > > -- > --Guido van Rossum (python.org/~guido) >
