require 'Qt' =begin The ClientSocket class provides a socket that is connected with a client. For every client that connects to the server, the server creates a new instance of this class. =end class ClientSocket < TQt::Socket def initialize(sock, parent=nil, name=nil) super( parent, name ) @line = 0 connect( self, SIGNAL('readyRead()'), SLOT('readClient()') ) connect( self, SIGNAL('connectionClosed()'), SLOT('deleteLater()') ) setSocket( sock ) end signals 'logText(const TQString&)' slots 'readClient()' def readClient() ts = TQt::TextStream.new( self ) while canReadLine() do str = ts.readLine() emit logText( tr("Read: '%s'\n" % str) ) ts << @line << ": " << str # 'endl' needs to be called like this in ruby endl(ts) emit logText( tr("Wrote: '%d: %s'\n" % [@line, str]) ) @line += 1 end ts.dispose() end end =begin The SimpleServer class handles new connections to the server. For every client that connects, it creates a new ClientSocket -- that instance is now responsible for the communication with that client. =end class SimpleServer < TQt::ServerSocket def initialize( parent=nil ) super( 4242, 1, parent ) if !ok() qWarning("Failed to bind to port 4242") exit(1) end end def newConnection( socket ) s = ClientSocket.new( socket, self ) emit newConnect( s ) end # The type of the argument is 'TQSocket*', not # 'ClientSocket*' as only types in the Smoke # library can be used for types in Signals signals 'newConnect(TQSocket*)' end =begin The ServerInfo class provides a small GUI for the server. It also creates the SimpleServer and as a result the server. =end class ServerInfo < TQt::VBox def initialize() super @server = SimpleServer.new( self ) itext = tr( "This is a small server example.\n" + "Connect with the client now." ) lb = TQt::Label.new( itext, self ) lb.setAlignment( AlignHCenter ) @infoText = TQt::TextView.new( self ) quit = TQt::PushButton.new( tr("Quit") , self ) # See the comment above about why the 'ClientSocket*' # type cannot be used connect( @server, SIGNAL('newConnect(TQSocket*)'), SLOT('newConnect(TQSocket*)') ) connect( quit, SIGNAL('clicked()'), $qApp, SLOT('quit()') ) end slots 'newConnect(TQSocket*)', 'connectionClosed()' def newConnect( s ) @infoText.append( tr("New connection\n") ) connect( s, SIGNAL('logText(const TQString&)'), @infoText, SLOT('append(const TQString&)') ) connect( s, SIGNAL('connectionClosed()'), SLOT('connectionClosed()') ) end def connectionClosed() @infoText.append( tr("Client closed connection\n") ) end end app = TQt::Application.new( ARGV ) info = ServerInfo.new app.mainWidget = info info.show app.exec