[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: TCPSocket hangs after ctrl-c

e

1/16/2005 3:59:00 PM

> Lähettäjä: Bjarke Bruun <bbj@swooplinux.org>
> Aihe: Re: TCPSocket hangs after ctrl-c
>
> On Sunday 16 January 2005 15:27, ts wrote:
> > >>>>> "B" == Bjarke Bruun <bbj@swooplinux.org> writes:
> >
> > B> I'm writing a small tcpserver and when I debug it and make changes
> > I B> have to stop the server and I get a hanging socket
> >
> > What class do you use for your server : TCPServer ?
>
> It's a small smtp server - just for fun... need to learn somethings
> about ruby and implementing rfc 821 seems well cool for starters :-)
>
> here is the core class (pre alpha everything you know :-))
>
> I've tried the "kill -9" and it seems to work, but I would like it to be
> done in code not on the CLI.
>
>
> ----
> # Author: Bjarke Bruun, bbj@swooplinux.org
> # Copyright: GPL version 2
>
> require 'socket'
> require 'config'
>
> # Process the commandline parameters
> $cli = CliInfo.new # don't mind this - it's just for setting some
> variables on the CLI.
>
> class Server
> def initialize
> @data = nil
> @f = File.new("rsmtp.log","a")
> ss = TCPServer.new '0.0.0.0', 10000
> server_going = true
> going = true
> while (@s = ss.accept) && server_going == true
> @f.puts("S: -> Client session established <-\n")
> fork {
> @s.print "220 Ruby SMTP Server/#{$cli.val("version")} \r\n"
>
> while going && @s.gets
> if $_ == "SERVER QUIT"
> # This is an attempt to send a "close" to the server so
> # it'll shut down proberly.
> server_going = false
> @s.close
> break
> end
> @f.puts("C: #{$_}")
> sleep 1
> r = cmd($_)
> @s.print r
> @f.puts("S: #{r}") if r != nil
> if r =~ /^354(.*)/
> r = getdata if r =~ /^354(.*)/
> @s.print r
> @f.puts("DEBUG > #{r}") if r != nil
> end
> if r =~ /^221(.*)/
> @f.puts("S: -> Quitting sesion successfully <- \n\n")
> @s.close
> going = false
> end
> end
> @s.close
> }
> end
> @s.close
> @f.close
> end
>
>
> def getdata
> #puts "DEBUG: Receiving data"
> @data = []
> while @s.gets !~ /^\./
> @data << $_
> @f.puts("\t#{@data[-1]}")
> end
> "250 message accepted\r\n"
> end
>
> def cmd line
> case line
> when /^HELO \[\d*.\d*.\d*.\d*\]/
> "250-#{$cli.val("SERVERNAME")} greets #{r}\r\n"
> when /^EHLO \[\d*.\d*.\d*.\d*\]/
> remote = line.split(/.\[/)
> "250 #{$cli.val("SERVERNAME")} greets
> #{remote[1].split("\]")}"#250-8BITMIME\r\n250-SIZE\r\n250-DSN\r\n250
> HELP"
> when /^MAIL FROM:(.*)/i
> @sndr = $1
> "250 OK\r\n" #: Sender okay\r\n"
> when /^RCPT TO:(.*)/i
> @rcpt = $1
> "250: Recipient okay\r\n"
> when /^DATA/i
> "354 Enter data, end with newline and '.'\r\n"
> when /^QUIT/i
> "221 closing connection\r\n"
> when /^RSET/i
> "250 okay\r\n"
> end
> end
>
> end
>
> # Run the server with logging enabled (it's a separate thread).
> server = Server.new

You do want to stop the program from the CLI but using a SIGTERM or
a SIGHUP rather than forcing a quit, right? I'd say it would be the
cleanest to trap the signal from your main process and then make sure
the child gets killed, too. Signal#trap and Process#abort should work
for that unless you want to set up a pipe/signal and bring the child
down more gracefully (in the event there's a read in progress).

Are you having problems with the SERVER QUIT command?

E