Is this socket code correct?
Lex Spoon
lex at cc.gatech.edu
Wed Nov 24 00:02:15 UTC 1999
Juan Cires Martinez <jcm at mat.upm.es> wrote:
> > Do you get to choose the protocol? If so, you might look at using
> > SimpleClientSocket, which has handy commands for sending/receiving a
> > line at a time, and for sending/receiving multi-line messages that
end
> > with a "." on a line by itself. It will take care of all the
> > waitForData's, etc, for you.
> >
> Thanks for the suggestion. Unfortunately, the protocol is fixed (and
> binary).
Oh well.
>
> > Otherwise, just remember that a read might return 0 bytes, so you
need
> > to program for it anyway. It's not hard to do, you probably need to
do
> > it anyway, and it asks less of the networking primitives.
>
> Yes, that's what I ended up doing:
>
> [socket dataAvailable] whileFalse:
> [(socket waitForDataUntil: Socket standardDeadline) ifFalse:
> [self error: 'Timeout reading reply']].
> buffer _ ByteArray new: 10000.
> read _ 0.
> [(read < 4) and: [socket dataAvailable]] "*"
> whileTrue: [read _ socket receiveDataInto: buffer]. "*"
>
> read < 4
> ifTrue: [self error: 'Too few data read'].
>
> This seems to work, but I worry that I wont be able to detect a
time-out
> if it happens during the second loop (the one marked "*") since I can
> have socket dataAvailable being true and receiveDataInto: reading 0
> bytes.
>
> Thanks, Juan.
You could wrap the loops together, and just remember to do a waitForData
before you readDataInto:. Also, you need to deal with the case where
you read 1 byte on one iteration, and 3 bytes on the next--you probably
don't want to completely overwrite your buffer. Here's a version that
should do what you want (though it's untested):
read _ 0.
[ read < 4 ] whileTrue: [
socket waitForDataUntil: Socket standardDeadline.
socket isConnected ifFalse: [ "deal with disconnects" ].
read _ read + (socket readDataInto: aStringOrByteArray startingAt: read+1).
].
To deal with timeouts, you probably need to compute the deadline up
front, instead of recomputing it each time you do a waitForData:
timeoutTime _ Socket standardDeadline. "calculate this up front"
[ read < 4 and: [ Time millisecondClockValue < timeoutTime ] ] whileTrue: [
socket waitForDataUntil: timeoutTime.
"...otherwise as above..."
].
read < 4 ifTrue: [ "timeout occured" ].
Good luck with your robots. It sounds fun!
Lex
More information about the Squeak-dev
mailing list
|