Hi All,
As a learning exercise I thought I would extend the Wiki Chatserver (http://sblinn.jottit.com/GNU_Smalltalk_SimpleEcho_TCP_Server) to create a simple forwarding proxy server. I'm hoping someone can give me a hand... Simply extending the example of the chat server could result in something like the code below... run | source | [ ss waitForConnection. source := (ss accept). [self handleSocket: source] fork ] repeat !! "Instance method to handle each connection" !SimpleProxyServer methodsFor: 'handling'! handleSocket: source | msg dest | dest := (TCP.Socket remote: amailserver port: 25). [ "handle source data" msg := (source nextHunk). msg displayOn: dest. dest flush. "handle dest data" msg := (dest nextHunk). msg displayOn: source. source flush. ] repeat !! ----------------------- But the code above wouldn't work since it blocks on input from source and there may be data in the dest Stream. So I modified handleSocket to look like this... run | source | [ ss waitForConnection. source := (ss accept). [self handleSocket: source] fork ] repeat !! "Instance method to handle each connection" !SimpleProxyServer methodsFor: 'handling'! handleSocket: source | msg dest | dest := (TCP.Socket remote: amailserver port: 25). [ "handle source data" (source available) ifTrue: [ msg := (source nextHunk). msg displayOn: dest. dest flush ]. "handle dest data" (dest available) ifTrue: [ msg := (dest nextHunk). msg displayOn: source. source flush ]. ] repeat !! ----------------------- And this is where I'd like a hand. The code above works as a relay but isn't suitable because: 1. It doesn't close the client (source) socket when the server (dest) socket closes. 2. The loop is CPU intensive I would like to know how to block until _either_ the "source" socket, or, the "dest" socket has some data. Also, if either of the source or dest sockets is closed then the thread should terminate and close any sockets owned by the thread. Thanks Stephen _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
> 1. It doesn't close the client (source) socket when the server (dest) > socket closes. > 2. The loop is CPU intensive You can use two processes. p1 := [ source ensureReadable. source isPeerAlive ifFalse: [ p1 terminate. p2 terminate ]. dest nextPutAllFlush: source nextHunk ] newProcess. p2 := [ dest ensureReadable. dest isPeerAlive ifFalse: [ p1 terminate. p2 terminate ]. source nextPutAllFlush: dest nextHunk ] newProcess. p1 resume. p2 resume In 3.0c there is no #nextHunk, so you can use StreamSocket to remove the write buffering and do p1 := [ source ensureReadable. source isPeerAlive ifFalse: [ p1 terminate. p2 terminate ]. source nextAvailablePutAllOn: dest ] newProcess. p2 := [ dest ensureReadable. dest isPeerAlive ifFalse: [ p1 terminate. p2 terminate ]. dest nextAvailablePutAllOn: source ] newProcess. p1 resume. p2 resume This has better performance because it does not do unnecessary copies and creation of objects. Paolo _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
In reply to this post by Stephen-71
Paolo Bonzini wrote:
> You can use two processes. > > p1 := [ > source ensureReadable. > source isPeerAlive ifFalse: [ p1 terminate. p2 terminate ]. > dest nextPutAllFlush: source nextHunk ] newProcess. > p2 := [ > dest ensureReadable. > dest isPeerAlive ifFalse: [ p1 terminate. p2 terminate ]. > source nextPutAllFlush: dest nextHunk ] newProcess. > > p1 resume. > p2 resume > > > In 3.0c there is no #nextHunk, so you can use StreamSocket to remove the > write buffering and do > > p1 := [ > source ensureReadable. > source isPeerAlive ifFalse: [ p1 terminate. p2 terminate ]. > source nextAvailablePutAllOn: dest ] newProcess. > p2 := [ > dest ensureReadable. > dest isPeerAlive ifFalse: [ p1 terminate. p2 terminate ]. > dest nextAvailablePutAllOn: source ] newProcess. > > p1 resume. > p2 resume > > > This has better performance because it does not do unnecessary copies > and creation of objects. > > Paolo > Thank you Paolo. I've found this solution extremely helpful. Thanks for putting the "new" solution in as well - that was going to be the next part of the exercise! Stephen _______________________________________________ help-smalltalk mailing list [hidden email] http://lists.gnu.org/mailman/listinfo/help-smalltalk |
Free forum by Nabble | Edit this page |