# Please note that I adapted this code from an ancient (5 year old) article on IBM's site. # I Forget the URL... require "socket" class ChatServer def initialize( port ) @sockets = [] @port = port end # initialize def run if @this_thread then false else @server_socket = TCPServer.new( "", @port ) @server_socket.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 ) printf("Chatserver started on port %d\n", @port) @sockets.push( @server_socket ) @this_thread = Thread.new(@server_socket, @sockets) { |server_socket, sockets| while true res = select( sockets, nil, nil, 0 ) if res # Iterate through the tagged read descriptors res[0].each do |sock| # Received a connect to the server (listening) socket if sock == server_socket accept_new_connection else # Received something on a client socket if sock.eof? str = sprintf("Client left %s:%s\n", sock.peeraddr[2], sock.peeraddr[1]) broadcast_string( str, sock ) sock.close sockets.delete(sock) else str = sprintf("[%s|%s]: %s", sock.peeraddr[2], sock.peeraddr[1], sock.gets()) broadcast_string( str, sock ) end#if end#if end#each end#if end#while } @this_thread.run true end#if end#def def stop @this_thread.kill if @this_thread @sockets.each { |socket| socket.close } @sockets = [] @this_thread = nil end private def broadcast_string( str, omit_sock ) puts str @sockets.each { |client_sock| client_sock.puts(str) unless client_sock == @server_socket || client_sock == omit_sock } end def accept_new_connection new_sock = @server_socket.accept @sockets.push new_sock new_sock.puts("You're connected to the Ruby chatserver") str = sprintf("Client joined %s:%s", new_sock.peeraddr[2], new_sock.peeraddr[1]) broadcast_string( str, new_sock ) end # accept_new_connection end #server