1# simple httpd 2 3# The code demonstrates how a multi-protocol daemon should be written. 4 5require "socket" 6require "thread" 7 8port = 8888 9res = Socket.getaddrinfo(nil, port, nil, Socket::SOCK_STREAM, nil, Socket::AI_PASSIVE) 10sockpool = [] 11names = [] 12threads = [] 13 14res.each do |i| 15 s = TCPServer.new(i[3], i[1]) 16 n = Socket.getnameinfo(s.getsockname, Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV).join(" port ") 17 sockpool.push s 18 names.push n 19end 20 21(0 .. sockpool.size - 1).each do |i| 22 mysock = sockpool[i] 23 myname = names[i] 24 STDERR.print "socket #{mysock} started, address #{myname}\n" 25 threads[i] = Thread.start do # Thread.start cannot be used here! 26 ls = mysock # copy to dynamic variable 27 t = Thread.current 28 STDERR.print "socket #{myname} listener started, pid #{$$} thread #{t}\n" 29 while true 30 as = ls.accept 31 Thread.start do 32 STDERR.print "socket #{myname} accepted, thread ", Thread.current, "\n" 33 s = as # copy to dynamic variable 34 str = '' 35 while line = s.gets 36 break if line == "\r\n" or line == "\n" 37 str << line 38 end 39 STDERR.print "socket #{myname} got string\n" 40 s.write("HTTP/1.0 200 OK\n") 41 s.write("Content-type: text/plain\n\n") 42 s.write("this is test: my name is #{myname}, you sent:\n") 43 s.write("---start\n") 44 s.write(str) 45 s.write("---end\n") 46 s.close 47 STDERR.print "socket #{myname} processed, thread ", Thread.current, " terminating\n" 48 end 49 end 50 end 51end 52 53for t in threads 54 t.join 55end 56