~~SLIDESHOW~~
www.swan.ac.uk
137.44.1.7
static InetAddress.getByName()
InetAddress
object containing address.Finds out your network address when you're connected to the Internet.
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/whoAmI.groovy
<cli prompt='$'> $ java WhoAmI Usage: WhoAmI MachineName $ java WhoAmI www.swan.ac.uk www.swan.ac.uk/137.44.1.7 </cli> May be useful if your ISP dynamically allocates IP addresses for your dial-up connection.
InputStream
and OutputStream
objects, which can then be converted to Reader
and Writer
objects.localhost
: the “local loopback” IP address for testing without a network InetAddress addr = InetAddress.getByName(null)
InetAddress.getByName("localhost")
InetAddress.getByName("127.0.0.1")
ServerSocket
isn't really a socket but more of a “Server Connector” that produces a Socket
as the return value of accept( )
, which waits for a connection.Socket
on each machine.Socket
, you call getInputStream()
and getOutputStream()
to produce the corresponding InputStream
and OutputStream
objectsBufferedReader
or BufferedWriter
and PrintWriter
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/javaServer.groovy
Explanation: references to listing …
ClientServer.PORT
and wait for a connectionextern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/javaClient.groovy
Explanation: references to code …
ClientServer.PORT
This slide shows a run of these programs.
Server started first: <cli prompt='>'> $ groovy javaServer.groovy </cli> client started in a second command shell window. <cli prompt='>'> $ groovy javaClient.groovy </cli>
ServerSocket.accept
can take a closure.withStreams
that takes a closure to the java.net.Socket
class. try
-catch
blocks. extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/groovyServer.groovy
Here we see how the use of closures simplify the logic of the server application, and also makes it much more readable. The necessary try
-catch
-finally
code that Java needs can be hidden inside the definition of the server.accept(Closure)
and socket.withStreams(Closure)
methods. Similar usability improvements are to be found throughout the Groovy-I/O system. Most commonly used cases are supported, but if you need tighter control, you can always go back to the full Java patterns.
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/groovyClient.groovy
Similarly, the client is made much more understandable by use of the socket.withStreams
method. You will also have noted the similarity of the actual code of the client/server logic.
Since the Groovy closure implements the Runnable
interface, to create a server that can handle multiple threads, we simply wrap the server.accept
closure in a while(true)
loop.
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/groovyMultiServer.groovy
When a new client request comes into the server, the accept
closure is activated in a new thread and the server can immediately go back to waiting.
// ... def address = InetAddress.getByName("127.0.0.1") while (true) { if (threadCount < MAX_THREADS) { Thread.start() { // ... def socket = new Socket(address, ClientServer.PORT) socket.withStreams { input, output -> // client-server code } // ... } } Thread.currentThread().sleep(100) }
Full listing in the notes.
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/groovyMultiClient.groovy
As before, we use the power of closures this time to continually create client threads, connect to the server, and echo some numbers before sending the end message and shutting down.
This slide shows a run of these programs.
As before the server started first: <cli prompt='>'> $ groovy groovyMultiServer.groovy </cli> client started in a second command shell window. <cli prompt='>'> $ groovy groovyMultiClient.groovy </cli>
The client and server will continue to run until you kill the processes (with windows <key>C-c</key>).
DatagramSocket
on both server and client.DatagramPacket
s.DatagramPacket
contains message of any length up to 64K bytes, IP address and socket # of destination.DatagramPacket
objects are used for holders of both sent and received datagramsDatagramPacket(buf, length)
DatagramPacket(buf, length, inetAddress, port)
buf
already contains data to be sent, length
is amount of buffer you want in datagram.Dgram
objects.Dgram
objects.-l
option lets you run a Groovy
script in client-server mode. -e
or by specifying a file) and groovy starts a TCP server on port 1960((Or another port if you wish to override it).<cli prompt=“>”> e:\dev\at-m42-2009\Examples\lecture10> groovy -l 5000 -e “println 'ip address: ' + InetAddress.getByName(line).hostAddress” </cli> Now in another command window: <cli prompt=“>”> e:\dev\at-m42-2009\Examples\lecture10> telnet localhost 5000 localhost ip address: 127.0.0.1 java.sun.com ip address: 72.5.124.55 www.swan.ac.uk ip address: 137.44.1.7 </cli>
When a script is started in listening mode, standard-output is attached to the socket's output stream and the messages from the socket's input stream are available line-by-line to the programmer in variable line
. Thus our echo server can be reimplemented as:
extern> http://www.cpjobling.org.uk/~eechris/at-m42/Examples/lecture10/simpleServer.groovy
Run this as <cli prompt='>'> e:\dev\at-m42-2009\Examples\lecture10> groovy -l 12345 simpleServer.groovy </cli> Then run any of the TCP clients developed earlier.
To demonstrate the power of Groovy, Jeremy Rayner, one of the core Groovy developers, wrote a simple HTTP server in less than 75 lines of code!
Listing is in the notes.
It really works: <cli prompt='>'> e:\dev\at-m42-2009\Examples\lecture10>groovy -l 80 SimpleWebServer.groovy </cli>
extern> http://svn.codehaus.org/groovy/trunk/groovy/groovy-core/src/examples/commandLineTools/SimpleWebServer.groovy
You may find that the examples scripts will not run in the PC lab because either Groovy or Java be prevented from openning a port by Windows Firewall. You won't have the necessary privileges to allow. Should work on your own machine.