Sean,

IMHO, you are correct to be unhappy.  In fairness, not only is half of the code 
"on the client" - half of it IS the client :)  It's just that the example is 
not very practical; no data are sent for the client to read.  The vast majority 
of (good) sockets programming is handling errors and non-responsive peers.

The most consistent story I have gotten is that ConnectionQueue is the 
preferred way to create a server; last I looked, it was broken, at least in 
Pharo.  It also offers no way, out of the box, to specify on which interface 
the server should be listening - that's kind of important.  Sadly, it polls for 
connections rather than blocking (just one Process, of course) until an event 
is generated as a client tries to connect.  It screams for some serious 
cleanup.  I have yet to look at what happens when, whether by socket or socket 
stream (which was not in the stream hierarchy and hence missing important 
protocol), the other side is non-responsive.  I doubt it will be ideal, which 
is to block only the Process attempting the connection.  Ditto that for DNS 
activity; only the process attempting it should suffer if the server is slow or 
completely unresponsive.  

IMHO, sockets should not have timeouts; they should simply block only the 
thread that initiates activity so that everything else moves along as expected. 
 On a server, a separate process can look for inactivity and terminate 
offending connections; on a client, either a similar watchdog or the user can 
make the call as to when to give up.  An event/announcement should be triggered 
off of a socket when its peer closes to enable timely cleanup.

Testing some of this stuff requires establishing lengthy I/O and powering off 
hubs at strategic times.  Until a system can survive that without hanging more 
than a calling thread, it's not ready.

Bill


testLocalServerAndClientNoThread
        "11-09 - try a server and a client in the same image.  Try without the 
separate read thread."

                | server port client serverSocket serverSocketStream text read |

        port := 4900.

        "11-09 - gag the prompter below"
        serverSocket := nil.

        server := ConnectionQueue portNumber:port queueLength:5.
        [
                client := SocketStream openConnectionToHostNamed:'localhost' 
port:port.
                [ serverSocket isNil ] whileTrue:[
                        serverSocket := server getConnectionOrNil.
                ].

                serverSocketStream := SocketStream on:serverSocket.
                text := 'Long live Tux!'.
                serverSocketStream nextPutAll:text; flush.

                read := client nextMany:text size.

                self should:[ read = text ].
                Transcript nextPutAll:'Just to make the point, we read: '; 
nextPutAll:read; cr; flush.

        ] ensure:[
                server destroy.
                serverSocketStream close.
                client close.
        ].

        "11-09 - no prompts"
        serverSocket := serverSocket.
        client := client.
        serverSocketStream := serverSocketStream.

        "
                NetworkSmokeTestCase prod:#testLocalServerAndClientNoThread.
        "


________________________________________
From: pharo-project-boun...@lists.gforge.inria.fr 
[pharo-project-boun...@lists.gforge.inria.fr] On Behalf Of Sean P. DeNigris 
[s...@clipperadams.com]
Sent: Sunday, August 29, 2010 5:05 PM
To: pharo-project@lists.gforge.inria.fr
Subject: [Pharo-project] Sockets in Pharo CollaborActive Book

The description of sockets at
http://book.pharo-project.org/book/networking/Socket/ is:

Socket is one of the main networking classes. You can create a new TCP
socket with the message #newTCP.
>
> This example creates a TCP socket and puts it into listening mode. After a
> client has connected, it reads data from the socket.
>
> | server client |
> server := Socket newTCP.
> server listenOn: 12345 backlogSize: 4.
> server waitForConnectionFor: 600.
> client := server accept.
> client receiveData
>

Huh?!  It looks like half the code in this snippet belongs on the server,
and the other half on the client.  I tried:
  Server doit:
    server := Socket newTCP.
    server listenOn: 12345 backlogSize: 4.
    server waitForConnectionFor: 600.
  Client doit:
    server := Socket newTCP.
    server listenOn: 12345 backlogSize: 4.
    server waitForConnectionFor: 600.
    client := server accept.
    client receiveData.
but the server just hung forever.

After flopping around for a while, and checking the swiki, it seemed to be
listenOn:backlogSize: that was the problem.  Everything went well with:
  Server DoIt:
    server := Socket newTCP.
    server listenOn: 8080.
    server waitForConnectionFor: 600.
    server sendData: 'Hello from the server'
  Client PrintIt:
    client := Socket newTCP.
    client connectTo: (NetNameResolver localHostAddress) port: 8080.
    client receiveData.

Anyway, I'd like to have this be clearer, but my knowledge is very basic.
Also, the class comment for socket reads "...Sockets are the lowest level of
networking object in Squeak and are not normally used directly..." so is
this where we want to direct people first?

Thanks.
Sean
--
View this message in context: 
http://forum.world.st/Sockets-in-Pharo-CollaborActive-Book-tp2399361p2399361.html
Sent from the Pharo Smalltalk mailing list archive at Nabble.com.

_______________________________________________
Pharo-project mailing list
Pharo-project@lists.gforge.inria.fr
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project

_______________________________________________
Pharo-project mailing list
Pharo-project@lists.gforge.inria.fr
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project

Reply via email to