Path: csiph.com!eternal-september.org!feeder.eternal-september.org!border1.nntp.ams1.giganews.com!nntp.giganews.com!newsfeed.xs4all.nl!newsfeed8.news.xs4all.nl!nzpost1.xs4all.net!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; 'broken': 0.03; '"""': 0.05; 'indicating': 0.05; '(of': 0.07; 'chunk': 0.07; 'newline': 0.07; 'only,': 0.07; 'socket': 0.07; '16-bit': 0.09; 'bsd': 0.09; 'delimiter': 0.09; 'fails.': 0.09; 'loop.': 0.09; 'message- id:@4ax.com': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'send()': 0.09; 'sockets': 0.09; 'python': 0.10; 'stack': 0.13; 'apps': 0.15; 'intermediate': 0.15; '"got': 0.16; '(there': 0.16; 'all"': 0.16; 'crop': 0.16; 'iteration': 0.16; 'received:80.91.229.3': 0.16; 'received:plane.gmane.org': 0.16; 'smtp,': 0.16; 'tcp': 0.16; 'worst': 0.16; "wouldn't": 0.16; 'bytes': 0.18; 'circular': 0.18; 'driver': 0.18; 'example.': 0.18; 'url:home': 0.18; '(not': 0.20; '2015': 0.20; 'extension': 0.20; 'converted': 0.22; 'dropped': 0.22; 'enforce': 0.22; 'problem:': 0.22; 'sends': 0.22; 'sep': 0.22; 'pass': 0.22; 'fit': 0.23; '(or': 0.23; 'originally': 0.23; 'passing': 0.23; 'header': 0.24; "doesn't": 0.26; 'header:X -Complaints-To:1': 0.26; 'helpful': 0.27; 'sequence': 0.27; 'yield': 0.27; 'function': 0.28; 'boundaries': 0.29; 'embed': 0.29; 'protocols': 0.29; 'that.': 0.30; 'code': 0.30; 'checked': 0.31; 'probably': 0.31; 'certain': 0.31; 'option': 0.31; "can't": 0.32; 'implement': 0.32; 'says': 0.32; 'embedded': 0.32; 'maybe': 0.33; 'stream': 0.33; "i'll": 0.33; 'handle': 0.34; 'gives': 0.35; 'could': 0.35; 'protocol': 0.35; 'skip:> 10': 0.35; 'supports': 0.35; 'but': 0.36; 'should': 0.36; 'there': 0.36; '(and': 0.36; 'to:addr:python-list': 0.36; 'subject:: ': 0.37; 'responsible': 0.37; 'client': 0.37; 'say': 0.37; 'received:org': 0.37; 'one,': 0.37; 'thought': 0.37; 'charset:us-ascii': 0.37; 'things': 0.38; 'drop': 0.38; 'wrong': 0.38; 'mean': 0.38; 'end': 0.39; 'goes': 0.39; 'data': 0.39; 'format': 0.39; 'does': 0.39; "didn't": 0.39; 'to:addr:python.org': 0.40; 'where': 0.40; 'space': 0.40; 'some': 0.40; 'field': 0.60; 'your': 0.60; 'skip:u 10': 0.61; 'entire': 0.61; 'back': 0.62; 'relatively': 0.63; 'more': 0.63; 'within': 0.64; 'due': 0.65; 'between': 0.65; 'limit': 0.65; 'believe': 0.66; 'internet': 0.70; 'receive': 0.71; 'integrity': 0.76; '(look': 0.84; 'end-user': 0.84; 'honored': 0.84; 'inherent': 0.84; 'receiver': 0.84; 'dennis': 0.91; 'fragment': 0.91; 'received:108': 0.93 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Dennis Lee Bieber Subject: Re: Lightwight socket IO wrapper Date: Sun, 20 Sep 2015 20:19:03 -0400 Organization: IISS Elusive Unicorn References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Gmane-NNTP-Posting-Host: adsl-108-68-178-61.dsl.klmzmi.sbcglobal.net X-Newsreader: Forte Agent 6.00/32.1186 X-No-Archive: YES X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list 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: 86 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1442794762 news.xs4all.nl 23822 [2001:888:2000:d::a6]:52827 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:96903 On Sun, 20 Sep 2015 23:36:30 +0100, "James Harris" declaimed the following: > >There are a few things and more crop up as time goes on. For example, >over TCP it would be helpful to have a function to receive a specific >number of bytes or one to read bytes until reaching a certain delimiter >such as newline or zero or space etc. Even better would be to be able to >use the iteration protocol so you could just code next() and get the >next such chunk of read in a for loop. When sending it would be good to >just say to send a bunch of bytes but know that you will get told how >many were sent (or didn't get sent) if it fails. Sock.sendall() doesn't >do that. Note that the "buffer size" option on a TCP socket.recv() gives you your "specific number of bytes" -- if available at that time. I wouldn't want to user .recv(1) though to implement your "reaching a certain delimiter"... Much better to read as much as available and search it for the delimiter. I'll confess, adding a .readln() FOR TCP ONLY, might be a nice extension over BSD sockets (might need to allow option for whether line-ends are Internet standard or some other marker, and whether they should be converted upon reading to the native format for the host). > >I thought UDP would deliver (or drop) a whole datagram but cannot find >anything in the Python documentaiton to guarantee that. In fact >documentation for the send() call says that apps are responsible for >checking that all data has been sent. They may mean that to apply to >stream protocols only but it doesn't state that. (Of course, UDP >datagrams are limited in size so the call may validly indicate >incomplete transmission even when the first part of a big message is >sent successfully.) > Looking in the wrong documentation You probably should be looking at the UDP RFC. Or maybe just http://www.diffen.com/difference/TCP_vs_UDP """ Packets are sent individually and are checked for integrity only if they arrive. Packets have definite boundaries which are honored upon receipt, meaning a read operation at the receiver socket will yield an entire message as it was originally sent. """ Even if the IP layer has to fragment a UDP packet to meet limits of the transport media, it should put them back together on the other end before passing it up to the UDP layer. To my knowledge, UDP does not have a size limit on the message (well -- a 16-bit length field in the UDP header). But since it /is/ "got it all" or "dropped" with no inherent confirmation, one would have to embed their own protocol within it -- sequence numbers with ACK/NAK, for example. Problem: if using LARGE UDP packets, this protocol would mean having LARGE resends should packets be dropped or arrive out of sequence (and since the ACK/NAK could be dropped too, you may have to handle the case of a duplicated packet -- also large). TCP is a stream protocol -- the protocol will ensure that all data arrives, and that it arrives in order, but does not enforce any boundaries on the data; what started as a relatively large packet at one end may arrive as lots of small packets due to intermediate transport limits (one can visualize a worst case: each TCP packet is broken up to fit Hollerith cards; 20bytes for header and 60 bytes of data -- then fed to a reader and sent on AS-IS). Boundaries are the end-user responsibility... line endings (look at SMTP, where an email message ends on a line containing just a ".") or embedded length counter (not the TCP packet length). >Receiving no bytes is taken as indicating the end of the communication. >That's OK for TCP but not for UDP so there should be a way to >distinguish between the end of data and receiving an empty datagram. > I don't believe UDP supports a truly empty datagram (length of 0) -- presuming a sending stack actually sends one, the receiving stack will probably drop it as there is no data to pass on to a client (there is a PR at work because we have a UDP driver that doesn't drop 0-length messages, but also can't deliver them -- so the circular buffer might fill with undeliverable headers) -- Wulfraed Dennis Lee Bieber AF6VN wlfraed@ix.netcom.com HTTP://wlfraed.home.netcom.com/