Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!ecngs!feeder2.ecngs.de!newsfeed.freenet.ag!news2.euro.net!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'subject:Python': 0.05; 'mrab': 0.05; 'say,': 0.05; 'chunk': 0.07; 'happen,': 0.07; 'json': 0.07; 'padding': 0.07; 'space.': 0.07; 'bytes,': 0.09; 'iterate': 0.09; 'length.': 0.09; 'loop.': 0.09; "wouldn't": 0.11; 'chunk:': 0.16; 'from:addr:mrabarnett.plus.com': 0.16; 'from:addr:python': 0.16; 'from:name:mrab': 0.16; 'input:': 0.16; 'integer.': 0.16; 'message-id:@mrabarnett.plus.com': 0.16; 'later': 0.16; 'wrote:': 0.17; 'bytes': 0.17; '>>>': 0.18; 'feb': 0.19; 'code.': 0.20; 'followed': 0.20; 'sort': 0.21; 'assuming': 0.22; "i'd": 0.22; 'insert': 0.23; 'split': 0.23; 'least': 0.25; 'header:In-Reply-To:1': 0.25; 'header:User-Agent:1': 0.26; '(which': 0.26; 'am,': 0.27; 'guess': 0.27; 'necessary.': 0.27; 'fixed': 0.28; 'chris': 0.28; 'initial': 0.28; '>>>>': 0.29; 'decimal': 0.29; 'character': 0.29; 'probably': 0.29; "i'm": 0.29; 'could': 0.32; '11,': 0.33; 'retain': 0.33; 'to:addr:python-list': 0.33; 'done': 0.34; 'pm,': 0.35; 'next': 0.35; 'but': 0.36; '12,': 0.36; 'data': 0.37; 'subject:: ': 0.38; 'easier': 0.38; 'some': 0.38; 'several': 0.39; 'to:addr:python.org': 0.39; 'received:192': 0.39; 'space': 0.39; 'received:192.168': 0.40; 'your': 0.60; 'save': 0.61; 'first': 0.61; 'between': 0.63; 'ever': 0.63; 'more': 0.63; 'header:Reply-To:1': 0.68; 'reply-to:no real name:2**0': 0.72; '2013': 0.84; 'reply-to:addr:python.org': 0.84; 'imagine': 0.96 X-CM-Score: 0.00 X-CNFS-Analysis: v=2.0 cv=XeZXOvF5 c=1 sm=1 a=0nF1XD0wxitMEM03M9B4ZQ==:17 a=Tv4_tr9OjFAA:10 a=ihvODaAuJD4A:10 a=OUOv7kDek9cA:10 a=8nJEP1OIZ-IA:10 a=EBOSESyhAAAA:8 a=8AHkEIZyAAAA:8 a=xZa4izBSp3IA:10 a=pGLkceISAAAA:8 a=gjNPJYCj3pwhiHhYgF8A:9 a=wPNLvfGTeEIA:10 a=MSl-tDqOz04A:10 a=QGznQY9FP867wdSZ:21 a=NbbXOort6_mQv1o0:21 a=0nF1XD0wxitMEM03M9B4ZQ==:117 X-AUTH: mrabarnett:2500 Date: Tue, 12 Feb 2013 03:09:51 +0000 From: MRAB User-Agent: Mozilla/5.0 (Windows NT 5.1; rv:17.0) Gecko/20130107 Thunderbird/17.0.2 MIME-Version: 1.0 To: python-list@python.org Subject: Re: Python recv loop References: <51190A32.7070105@mrabarnett.plus.com> <6F9402BA-4753-4543-A8E7-05E5234660EA@grep.my> In-Reply-To: Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list Reply-To: python-list@python.org List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 50 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1360638583 news.xs4all.nl 6902 [2001:888:2000:d::a6]:44389 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:38718 On 2013-02-12 02:20, Chris Angelico wrote: > On Tue, Feb 12, 2013 at 12:41 PM, Ihsan Junaidi Ibrahim wrote: >> >> On Feb 11, 2013, at 11:24 PM, Chris Angelico wrote: >> >>> On Tue, Feb 12, 2013 at 2:11 AM, MRAB wrote: >>>> I probably wouldn't make it fixed length. I'd have the length in >>>> decimal followed by, say, "\n". >>> >>> Or even "followed by any non-digit". Chances are your JSON data begins >>> with a non-digit, so you'd just have to insert a space in the event >>> that you're JSON-encoding a flat integer. (Which might not ever >>> happen, if you know that your data will always be an object.) >>> >>> ChrisA >> >> So on the first recv() call, I set the buffer at 1 character and I iterate >> over single character until a non-digit character is encountered? > > More efficient would be to guess that it'll be, say, 10 bytes, and > then retain any excess for your JSON read loop. But you'd need to sort > that out between the halves of your code. > If the length is always followed by a space then it's easier to split it off the input: buf = sock.recv(10) space_pos = buf.find(b" ") nbuf = int(buf[ : space_pos]) buf = buf[space_pos+ 1 : ] while len(buf) < nbuf: chunk = sock.recv(nbuf - len(buf)) if not chunk: break buf += chunk I'm assuming that: 1. The initial recv returns the length followed by a space. It could, of course, return fewer bytes (space_pos == -1), so you may need to recv some more bytes, like what's done later on. 2. At least 10 bytes were sent. Imagine what would happen if the sender sent b"2 []" immediately followed by b"2 []". The initial recv could return all of it. In that case you could save the excess until next time. Alternatively, the sender could guarantee that it would never send fewer than the 10 bytes, padding with several b" " if necessary.