19 Jul 11:07
Re: advice on efficient socket programming sought
From: Klaus D. Witzel <klaus.witzel <at> cobss.com>
Subject: Re: advice on efficient socket programming sought
Newsgroups: gmane.comp.lang.smalltalk.squeak.general
Date: 2008-07-19 09:07:02 GMT
Subject: Re: advice on efficient socket programming sought
Newsgroups: gmane.comp.lang.smalltalk.squeak.general
Date: 2008-07-19 09:07:02 GMT
Hi Philippe, on Sat, 19 Jul 2008 09:11:20 +0200, you wrote: > 2008/7/18 Janko Mivšek: >> Hi Philippe, >> >> By efficient you mean receiving and sending a lot such data? Or what >> kind of >> efficiency you want to achieve? > > The data comes in chunks up to 8k. I just want to read it fast with as > little unnecessary copies as possible. Same for writing. I do sort of this, taking the buffer's size from the actual network's capabilities. Also, I only send/receive strings, the user must know what a string is for socket in Squeak. The first k characters (k digits, delimiter is Character space) that I send/receive are # of characters of the whole string. So I have no 8k limit, the limit I make use of is the underlying TCP/IP stack's/socket's capabilities (which may be influenced by hw/vendor limitations and/or plugin's consideration). But as with networking in general: only less is more, for example it would be worth considering MTU when sending (if you can find out from Smalltalk/plugin is another matter). Ping some "far, far away" IP addresses with 32 bytes and then with 8k to see the difference (or see one of the routers complaining ;) Back to Smalltalk, pasted from my NetworkContext.st: >> #createBuffer buffer := String new: ((socket getOption: 'SO_RCVBUF') at: 2). position := 0 >> #receiveSomeData ^ position := position + (socket receiveSomeDataInto: buffer startingAt: position + 1) >> #sendData: aString "user is expected to send chunks in size of buffer" ^ socket sendData: aString >> #waitForData ^ socket waitForDataFor: nTimeUnits "YMMV" >> #fetchFromBuffer | chunk | (buffer == nil or: [position == nil]) ifTrue: [self createBuffer; waitForData; receiveSomeData] ifFalse: [socket dataAvailable ifTrue: [self receiveSomeData]]. "if not enough available, ^ self fetchFromBuffer" "now process from buffer whatever there was made available" "copy available chars to chunk or (re-)use some writeStream" "adjust position and copy remainder to buffer's beginning" ^ chunk Observe use of the words "seconds" and "milliseconds" for timeout units in the comments of Socket implementation. For other possible misunderstandings with Squeak socket's ifClosed: ifTimeOut: (I didn't paste these if's into the above) see - http://bugs.squeak.org/view.php?id=6951 - http://lists.squeakfoundation.org/pipermail/squeak-dev/2008-February/125927.html HTH. /Klaus > Cheers > Philippe
RSS Feed