Hello all, I've been trying to figure out how to read from a Socket and not have it block. So, I have my stream: ioStream := aSocketAccessor readAppendStream. ioStream lineEndCRLF. Now, I either want a non-blocking ioStream upTo: Character cr. "Yes, I'm reading one line of text at a time." or something like: "If there's data, return that data, otherwise return nil." ^ ioStream hasDataReady ifTrue: [ ioStream upTo: Character cr ] ifFalse: [ nil ]. But, for the life of me, I can't figure it out. #isEmpty doesn't do it (it always returns true), and #atEnd/#atEndOfData block. Any help or ideas would be appreciated. - M. -- Marco Qualizza - (613) 895-2078 "Elegance is not optional." (Richard O'Keefe) |
This is actually kinda tricky especially with the Streams involved. You
can check a SocketAccessor if it has any pending unread data using #bytesForRead. So aSocketAccessor bytesForRead should tell you if there is data in the OS socket buffers ready to be read in (I think). However socket streams use internal buffering, so you'd really also need to check if there's anything left in the stream buffer that you didn't pull out of the stream yet. I'm not even sure how to do that (#basicAtEnd maybe, but that's private anyway). Note that even if you were able to do that. You still can't simply issue an 'upTo: CR' because if there's no CR in that pending data, you'll end up blocked at the end of it anyway. Personally, I always found that when I needed this sort of control, the stream was just getting in the way. It's usually easier to just drop to the socket level and use the #readInto:/writeFrom: and #readWaitWithTimeout: API. You can find more on that in the documentation on sockets (used to be in NetClientDevGuide.pdf before, now in 7.4 it's in BasicLibraries.pdf, I believe). Once you get the bytes into the image you can start streaming over it using internal streams. HTH, Martin Marco Qualizza wrote: > Hello all, > > I've been trying to figure out how to read from a Socket and not have it block. So, I have my stream: > > ioStream := aSocketAccessor readAppendStream. > ioStream lineEndCRLF. > > Now, I either want a non-blocking > > ioStream upTo: Character cr. "Yes, I'm reading one line of text at a time." > > or something like: > > "If there's data, return that data, otherwise return nil." > ^ ioStream hasDataReady > ifTrue: [ ioStream upTo: Character cr ] > ifFalse: [ nil ]. > > But, for the life of me, I can't figure it out. #isEmpty doesn't do it (it always returns true), and #atEnd/#atEndOfData block. > > Any help or ideas would be appreciated. > > - M. > |
Hello Martin, I'm writing what is effectively a telnet server, so there are no issues with partial lines (ie/ having data and not having it crlf-terminated). I've just tried #bytesForRead, and it seems to do the trick. You've raised a good point regarding buffering, I'll have to look into it. Thanks, - M. Wednesday, January 18, 2006, 10:02:37 PM, you wrote: > This is actually kinda tricky especially with the Streams involved. You > can check a SocketAccessor if it has any pending unread data using > #bytesForRead. So > aSocketAccessor bytesForRead > should tell you if there is data in the OS socket buffers ready to be > read in (I think). > However socket streams use internal buffering, so you'd really also need > to check if there's anything left in the stream buffer that you didn't > pull out of the stream yet. I'm not even sure how to do that > (#basicAtEnd maybe, but that's private anyway). > Note that even if you were able to do that. You still can't simply issue > an 'upTo: CR' because if there's no CR in that pending data, you'll end > up blocked at the end of it anyway. > Personally, I always found that when I needed this sort of control, the > stream was just getting in the way. It's usually easier to just drop to > the socket level and use the #readInto:/writeFrom: and > #readWaitWithTimeout: API. You can find more on that in the > documentation on sockets (used to be in NetClientDevGuide.pdf before, > now in 7.4 it's in BasicLibraries.pdf, I believe). > Once you get the bytes into the image you can start streaming over it > using internal streams. > HTH, > Martin > Marco Qualizza wrote: >> Hello all, >> I've been trying to figure out how to read from a Socket and not have it block. So, I have my stream: >> ioStream := aSocketAccessor readAppendStream. >> ioStream lineEndCRLF. >> Now, I either want a non-blocking >> ioStream upTo: Character cr. "Yes, I'm reading one line of text at a time." >> or something like: >> "If there's data, return that data, otherwise return nil." >> ^ ioStream hasDataReady >> ifTrue: [ ioStream upTo: Character cr ] >> ifFalse: [ nil ]. >> But, for the life of me, I can't figure it out. #isEmpty doesn't do it (it always returns true), and #atEnd/#atEndOfData block. >> Any help or ideas would be appreciated. >> - M. -- Marco Qualizza - (613) 895-2078 "Elegance is not optional." (Richard O'Keefe) |
Free forum by Nabble | Edit this page |