> LçÉettçËäº 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