How to debug socket use
Last updated at 3:58 pm UTC on 14 January 2006
Question: Richard Staehli Can anyone suggest how to write and debug a very simple use of sockets? My attempts at writing a remote invocation protocol have been frustrated by inability to get two squeak processes to talk on the same machine.
What does work is to start a server (PWS) in process 1, listening on port 8000, then connecting via a client (Scamper) in process 2.
When I try my code in place of the client, it succeeds in connecting, and a few times even got replies from the server, but more often it just hangs, waiting for a reply. Here's the code:
Transcript show: 'connected to addr: ',addr printString,
'port: ',port printString; cr.
socket sendData: protocolHandler stream contents.
Transcript show: 'done'; cr.
Transcript show: 'QRMIMessage reading... '; cr.
[socket isConnected] whileTrue: [
(socket waitForDataUntil: (Socket deadlineSecs: 5)) ifFalse: [
Transcript show: 'data was late'; cr
bytes _ socket receiveDataInto: buf.
Transcript show: 'read:',bytes printString; cr.
1 to: bytes do: [:i | serialization nextPut: (buf at: i)].
totalBytes _ totalBytes + bytes.
And here is the typical Transcript output:
connected to addr: a ByteArray(127 0 0 1) port: 8000
data was late
Answer: Goran Krampe
1. Make sure the Processes yield to each other. For example I think you should run them in lower priorities so that they get preempted by another Process running in a higher prio. I think this was a good thing to do IIRC.
2. You can play with the SharedStreams package to "emulate" Sockets. In a previous project we built the SharedBidirectionalStream to work as a replacement for SocketStream (a multi-demultiplexer so that multiple connections could be run over a single socket). Anyway, in that project we successfully had multiple unit tests setting up servers and running clients from and to the same image - so it can be done. But as I said - you might need to play with the Process prios.
3. You should use SocketStream - no need to be messing around at the Socket layer anymore IMHO.
Question: Richard Staehli
[Regarding #1], It is working now with "Server defaultPriority". By the way, I meant OS processes, not Smalltalk processes, but I understand that it can be simpler to debug in one image.
Question: Richard Staehli [Regarding #3], This was a great help, once I updated from 3.6 to 3.7. Perhaps the 3.6 stuff was just buggy for my purpose.
Answer: Goran Krampe The first incarnation of SocketStream was in Comanche, but the one in 3.7 is a rewrite of it from Michael Rueger. Later versions of Comanche, currently named KomHttpServer uses the one now in 3.7.
Question: Richard Staehli I'm still learning about the new stuff: SocketStream and the Server classes. It appears that SocketStream is not a substitute for Socket in that you can't "listen" on a SocketStream. Also, SocketStream does not support #store, #skipTo: and other protocol assumed by Smalltalk serialization code. I'm not sure whether to code around this or extend SocketStream.
Answer: I would probably look into extending SocketStream since it IMHO should be able to work as a Stream as much as possible. Just my gut feeling. And since it is pretty new it can surely be missing things. For making servers, promise me to take a look at KomHttpServer - there is a lot of good stuff in there! :)