Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #96908 > unrolled thread

Re: Lightwight socket IO wrapper

Started byChris Angelico <rosuav@gmail.com>
First post2015-09-21 12:40 +1000
Last post2015-09-21 13:26 +0100
Articles 9 — 4 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: Lightwight socket IO wrapper Chris Angelico <rosuav@gmail.com> - 2015-09-21 12:40 +1000
    Re: Lightwight socket IO wrapper Marko Rauhamaa <marko@pacujo.net> - 2015-09-21 07:39 +0300
      Re: Lightwight socket IO wrapper Chris Angelico <rosuav@gmail.com> - 2015-09-21 14:48 +1000
        Re: Lightwight socket IO wrapper Marko Rauhamaa <marko@pacujo.net> - 2015-09-21 09:56 +0300
      Re: Lightwight socket IO wrapper Michael Ströder <michael@stroeder.com> - 2015-09-21 09:02 +0200
        Re: Lightwight socket IO wrapper Marko Rauhamaa <marko@pacujo.net> - 2015-09-21 10:57 +0300
          Re: Lightwight socket IO wrapper Michael Ströder <michael@stroeder.com> - 2015-09-21 10:29 +0200
            Re: Lightwight socket IO wrapper Marko Rauhamaa <marko@pacujo.net> - 2015-09-21 11:47 +0300
              Re: Lightwight socket IO wrapper MRAB <python@mrabarnett.plus.com> - 2015-09-21 13:26 +0100

#96908 — Re: Lightwight socket IO wrapper

FromChris Angelico <rosuav@gmail.com>
Date2015-09-21 12:40 +1000
SubjectRe: Lightwight socket IO wrapper
Message-ID<mailman.17.1442803211.28679.python-list@python.org>
On Mon, Sep 21, 2015 at 11:55 AM, Cameron Simpson <cs@zip.com.au> wrote:
> On 21Sep2015 10:34, Chris Angelico <rosuav@gmail.com> wrote:
>>
>> If you're going to add sequencing and acknowledgements to UDP,
>> wouldn't it be easier to use TCP and simply prefix every message with
>> a two-byte length?
>
>
> Frankly, often yes. That's what I do. (different length encoding, but
> otherwise...)

Out of interest, what encoding? With most protocols, I would prefer to
encode in ASCII digits terminated by end-of-line, but for arbitrary
content you're packaging up, it's usually easier to read 2 bytes (or 4
or whatever you want to specify), then read that many bytes, and
that's your content. No buffering required - you'll never read past
the end of a packet.

> UDP's neat if you do not care if a packet fails to arrive and if you can
> guarentee that your data fits in a packet in the face of different MTUs.
> I like TCP myself, most of the time. Another nice thing about TCP is that
> wil a little effort you get to pack multiple data packets (or partial data
> packets) into a network packet, etc.

Emphatically - a little effort sometimes, and other times no effort at
all! If you write a packet of data, then write another one, and
another, and another, and another, without waiting for responses,
Nagling should combine them automatically. And even if they're not
deliberately queued by Nagle's Algorithm, packets can get combined for
other reasons. So, yeah! Definitely can help a lot with packet counts
on small writes.

ChrisA

[toc] | [next] | [standalone]


#96912

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-09-21 07:39 +0300
Message-ID<876134e683.fsf@elektro.pacujo.net>
In reply to#96908
Chris Angelico <rosuav@gmail.com>:

> On Mon, Sep 21, 2015 at 11:55 AM, Cameron Simpson <cs@zip.com.au> wrote:
>> Another nice thing about TCP is that wil a little effort you get to
>> pack multiple data packets (or partial data packets) into a network
>> packet, etc.
>
> Emphatically - a little effort sometimes, and other times no effort at
> all! If you write a packet of data, then write another one, and
> another, and another, and another, without waiting for responses,
> Nagling should combine them automatically. And even if they're not
> deliberately queued by Nagle's Algorithm, packets can get combined for
> other reasons. So, yeah! Definitely can help a lot with packet counts
> on small writes.

Unfortunately, Nagle and delayed ACK, which are both defaults, don't go
well together (you get nasty 200-millisecond hickups).

I recommend using socket.TCP_CORK with socket.TCP_NODELAY where they are
available (Linux). They give you Nagle without delayed ACK. See

   <URL: http://linux.die.net/man/7/tcp>


As for the topic, TCP doesn't need wrappers to abstract away the
difficult bits. That's a superficially good idea that leads to trouble.


Marko

[toc] | [prev] | [next] | [standalone]


#96913

FromChris Angelico <rosuav@gmail.com>
Date2015-09-21 14:48 +1000
Message-ID<mailman.20.1442810914.28679.python-list@python.org>
In reply to#96912
On Mon, Sep 21, 2015 at 2:39 PM, Marko Rauhamaa <marko@pacujo.net> wrote:
> Chris Angelico <rosuav@gmail.com>:
>
>> On Mon, Sep 21, 2015 at 11:55 AM, Cameron Simpson <cs@zip.com.au> wrote:
>>> Another nice thing about TCP is that wil a little effort you get to
>>> pack multiple data packets (or partial data packets) into a network
>>> packet, etc.
>>
>> Emphatically - a little effort sometimes, and other times no effort at
>> all! If you write a packet of data, then write another one, and
>> another, and another, and another, without waiting for responses,
>> Nagling should combine them automatically. And even if they're not
>> deliberately queued by Nagle's Algorithm, packets can get combined for
>> other reasons. So, yeah! Definitely can help a lot with packet counts
>> on small writes.
>
> Unfortunately, Nagle and delayed ACK, which are both defaults, don't go
> well together (you get nasty 200-millisecond hickups).

Only in the write-write-read scenario. If you write-read-write-read,
or if your reads don't depend on your writes, then Nagle + delayed ACK
works just fine. But if you write a bunch of stuff, then block waiting
for the other end to respond, and then write multiple times, and wait
for a response, _then_ the pair work badly together, yes.

> As for the topic, TCP doesn't need wrappers to abstract away the
> difficult bits. That's a superficially good idea that leads to trouble.

Depends what you're doing - if you're working with a higher level
protocol like HTTP, then abstracting away the difficult bits of TCP is
part of abstracting away the difficult bits of HTTP, and something
like 'requests' is superb. But if you're inventing your own protocol,
directly on top of a BSD socket, then I would agree - just call socket
functions directly. Otherwise you risk nasty surprises when your
file-like object has ridiculous performance problems.

ChrisA

[toc] | [prev] | [next] | [standalone]


#96917

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-09-21 09:56 +0300
Message-ID<87fv28p8er.fsf@elektro.pacujo.net>
In reply to#96913
Chris Angelico <rosuav@gmail.com>:

> On Mon, Sep 21, 2015 at 2:39 PM, Marko Rauhamaa <marko@pacujo.net> wrote:
>> Chris Angelico <rosuav@gmail.com>:
>>
>>> If you write a packet of data, then write another one, and another,
>>> and another, and another, without waiting for responses, Nagling
>>> should combine them automatically. [...]
>>
>> Unfortunately, Nagle and delayed ACK, which are both defaults, don't go
>> well together (you get nasty 200-millisecond hickups).
>
> Only in the write-write-read scenario.

Which is the case you brought up. Ideally, application code should be
oblivious to the inner heuristics of the TCP implementation. IOW,
write-write-read is perfectly valid and shouldn't lead to performance
degradation.

Unfortunately, the socket API doesn't provide a standard way for the
application to tell the kernel that it is done sending for now. Linux's
TCP_CORK+TCP_NODELAY is a nonstandard way but does the job quite nicely.

>> As for the topic, TCP doesn't need wrappers to abstract away the
>> difficult bits. That's a superficially good idea that leads to
>> trouble.
>
> Depends what you're doing - if you're working with a higher level
> protocol like HTTP, then abstracting away the difficult bits of TCP is
> part of abstracting away the difficult bits of HTTP, and something
> like 'requests' is superb.

Naturally, a higher-level protocol hides the lower-level protocol. It in
turn has intricacies of its own. Unfortunately, Python's stdlib HTTP
facilities are too naive (ie, blocking, incompatible with asyncio) to be
usable.


Marko

[toc] | [prev] | [next] | [standalone]


#96918

FromMichael Ströder <michael@stroeder.com>
Date2015-09-21 09:02 +0200
Message-ID<mto9ud$2ui$1@dont-email.me>
In reply to#96912
Marko Rauhamaa wrote:
> I recommend using socket.TCP_CORK with socket.TCP_NODELAY where they are
> available (Linux).

If these options are not available are both option constants also not
available? Or does the implementation have to look into sys.platform?

Ciao, Michael.

[toc] | [prev] | [next] | [standalone]


#96920

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-09-21 10:57 +0300
Message-ID<87a8sgp5ln.fsf@elektro.pacujo.net>
In reply to#96918
Michael Ströder <michael@stroeder.com>:

> Marko Rauhamaa wrote:
>> I recommend using socket.TCP_CORK with socket.TCP_NODELAY where they
>> are available (Linux).
>
> If these options are not available are both option constants also not
> available? Or does the implementation have to look into sys.platform?

   >>> import socket
   >>> 'TCP_CORK' in dir(socket)
   True

The TCP_NODELAY option is available everywhere but has special semantics
with TCP_CORK.


Marko

[toc] | [prev] | [next] | [standalone]


#96924

FromMichael Ströder <michael@stroeder.com>
Date2015-09-21 10:29 +0200
Message-ID<mtof26$j1p$1@dont-email.me>
In reply to#96920
Marko Rauhamaa wrote:
> Michael Ströder <michael@stroeder.com>:
> 
>> Marko Rauhamaa wrote:
>>> I recommend using socket.TCP_CORK with socket.TCP_NODELAY where they
>>> are available (Linux).
>>
>> If these options are not available are both option constants also not
>> available? Or does the implementation have to look into sys.platform?
> 
>    >>> import socket
>    >>> 'TCP_CORK' in dir(socket)
>    True

On which platform was this done?

To rephrase myquestion:
How to automagically detect whether TCP_CORK is really available on a platform?

'TCP_CORK' in dir(socket)
or catch AttributeError

sys.platform=='linux2'
hoping that Linux 2.1 or prior is not around anymore...

...

Ciao, Michael.

[toc] | [prev] | [next] | [standalone]


#96927

FromMarko Rauhamaa <marko@pacujo.net>
Date2015-09-21 11:47 +0300
Message-ID<87wpvknoq8.fsf@elektro.pacujo.net>
In reply to#96924
Michael Ströder <michael@stroeder.com>:

> Marko Rauhamaa wrote:
>> Michael Ströder <michael@stroeder.com>:
>> 
>>> Marko Rauhamaa wrote:
>>>> I recommend using socket.TCP_CORK with socket.TCP_NODELAY where they
>>>> are available (Linux).
>>>
>>> If these options are not available are both option constants also not
>>> available? Or does the implementation have to look into sys.platform?
>> 
>>    >>> import socket
>>    >>> 'TCP_CORK' in dir(socket)
>>    True
>
> On which platform was this done?

Python3 on Fedora 21.
Python2 on RHEL4.

Sorry, don't have non-Linux machines to try.

> How to automagically detect whether TCP_CORK is really available on a
> platform?

I sure hope 'TCP_CORK' in dir(socket) evaluates to False on non-Linux
machines.


Marko

[toc] | [prev] | [next] | [standalone]


#96936

FromMRAB <python@mrabarnett.plus.com>
Date2015-09-21 13:26 +0100
Message-ID<mailman.33.1442838425.28679.python-list@python.org>
In reply to#96927
On 2015-09-21 09:47, Marko Rauhamaa wrote:
> Michael Ströder <michael@stroeder.com>:
>
>> Marko Rauhamaa wrote:
>>> Michael Ströder <michael@stroeder.com>:
>>>
>>>> Marko Rauhamaa wrote:
>>>>> I recommend using socket.TCP_CORK with socket.TCP_NODELAY where they
>>>>> are available (Linux).
>>>>
>>>> If these options are not available are both option constants also not
>>>> available? Or does the implementation have to look into sys.platform?
>>>
>>>    >>> import socket
>>>    >>> 'TCP_CORK' in dir(socket)
>>>    True
>>
>> On which platform was this done?
>
> Python3 on Fedora 21.
> Python2 on RHEL4.
>
> Sorry, don't have non-Linux machines to try.
>
>> How to automagically detect whether TCP_CORK is really available on a
>> platform?
>
> I sure hope 'TCP_CORK' in dir(socket) evaluates to False on non-Linux
> machines.
>
On Windows 10:

Python 3.5.0 (v3.5.0:374f501f4567, Sep 13 2015, 02:27:37) [MSC v.1900 64 
bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
 >>> import socket
 >>> 'TCP_CORK' in dir(socket)
False
 >>>

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web