[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... Sent from the Pharo Smalltalk mailing list archive at Nabble.com.
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-bounces@lists.gforge.inria.fr [pharo-project-bounces@lists.gforge.inria.fr] On Behalf Of Sean P. DeNigris [sean@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... 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
Hi, I'm currently working on a chapter about Sockets for the Pharo by example book. I'm half way, though there is more material than what is on the pharo collabor-active book. It's a pitty, that pharo by example and the collaborative book aren't linked. Any way, I'll be happy ot send what I have written to anyone who request it. Noury On 29 août 2010, at 23:05, Sean P. DeNigris wrote:
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... 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
Noury
Noury, I would like a copy. Bill bschwab AT anest DOT ufl DOT edu ________________________________________ From: pharo-project-bounces@lists.gforge.inria.fr [pharo-project-bounces@lists.gforge.inria.fr] On Behalf Of Noury Bouraqadi [bouraqadi@gmail.com] Sent: Monday, August 30, 2010 9:41 AM To: Pharo-project@lists.gforge.inria.fr Subject: Re: [Pharo-project] Sockets in Pharo CollaborActive Book Hi, I'm currently working on a chapter about Sockets for the Pharo by example book. I'm half way, though there is more material than what is on the pharo collabor-active book. It's a pitty, that pharo by example and the collaborative book aren't linked. Any way, I'll be happy ot send what I have written to anyone who request it. Noury On 29 août 2010, at 23:05, Sean P. DeNigris wrote:
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... 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
Noury _______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Hi all! Two notes (no, haven't read all posts on this subject): 1. IMHO for almost 99% of your needs you would use SocketStream and not Socket directly to write a socket client. I wrote the current SocketStream implementation and I have written several clients using it - like the latest StompProtocol on SS etc. Please, please, use SocketStream in your introduction to socket client programming! 2. I haven't looked at Andreas' new WebServer but I presume it is a "standard" forking server just like the old Comanche/KomHttpServer codebase is. A while back I wrote Blackfoot - a SimpleCGI implementation and then I extracted the essential "forking Socket server" code from KomHttpServer so that it can be easily understood and reused. I tend to point to Blackfoot as a very good "example" to use in this regard. We could even split out the generic part as a "standard class" to use. In fact, Stephen Pair did this with the TcpServices library a long time ago when he rewrote Comanche into KomHttpServer BUT... I think it got a bit overengineered and would instead point to Blackfoot as a good candidate for such a "SocketServer" class. regards, Göran
On Sep 1, 2010, at 8:58 AM, Göran Krampe wrote:
Hi all!
Two notes (no, haven't read all posts on this subject):
1. IMHO for almost 99% of your needs you would use SocketStream and not Socket directly to write a socket client. I wrote the current SocketStream implementation and I have written several clients using it - like the latest StompProtocol on SS etc. Please, please, use SocketStream in your introduction to socket client programming!
Yes this is the missing section in noury/luc chapter :)
2. I haven't looked at Andreas' new WebServer but I presume it is a "standard" forking server just like the old Comanche/KomHttpServer codebase is. A while back I wrote Blackfoot - a SimpleCGI implementation and then I extracted the essential "forking Socket server" code from KomHttpServer so that it can be easily understood and reused. I tend to point to Blackfoot as a very good "example" to use in this regard. We could even split out the generic part as a "standard class" to use. In fact, Stephen Pair did this with the TcpServices library a long time ago when he rewrote Comanche into KomHttpServer BUT... I think it got a bit overengineered and would instead point to Blackfoot as a good candidate for such a "SocketServer" class.
sound cool do you have a little 2 pages intro to blackfoot? Stef
regards, Göran
_______________________________________________ Pharo-project mailing list Pharo-project@lists.gforge.inria.fr http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Hi! On 09/01/2010 10:04 AM, Stéphane Ducasse wrote:
2. I haven't looked at Andreas' new WebServer but I presume it is a "standard" forking server just like the old Comanche/KomHttpServer codebase is. A while back I wrote Blackfoot - a SimpleCGI implementation and then I extracted the essential "forking Socket server" code from KomHttpServer so that it can be easily understood and reused. I tend to point to Blackfoot as a very good "example" to use in this regard. We could even split out the generic part as a "standard class" to use. In fact, Stephen Pair did this with the TcpServices library a long time ago when he rewrote Comanche into KomHttpServer BUT... I think it got a bit overengineered and would instead point to Blackfoot as a good candidate for such a "SocketServer" class.
sound cool do you have a little 2 pages intro to blackfoot?
Blackfoot in itself is a SimpleCGI implementation, I presented it on an OOPSLA back in... 2006 or so: http://goran.krampe.se/Blackfoot.pdf ...but my point was that it can easily serve as a good SIMPLE example of a forking Socket server using SocketStream. It is VERY small and IIRC the base "forking Socket server" is separate. regards, Göran
participants (5)
-
Göran Krampe -
Noury Bouraqadi -
Schwab,Wilhelm K -
Sean P. DeNigris -
Stéphane Ducasse