Java NIO時間服務器示例
在本示例中,實現時間服務器。服務器監聽連接,並向連接的客戶端發送當前服務器的時間。這是一個簡單的阻塞程序,演示NIO套接字通道(接受和寫入),緩衝區處理,字符集和正則表達式。
在本示例中共有兩個Java程序文件,它們分別爲:TimeServer.java和TimeQuery.java,如下所示 -
TimeServer.java充當服務器端,代碼如下所示 -
package com.yiibai;
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.*;
/* Listen for connections and tell callers what time it is.
* Demonstrates NIO socket channels (accepting and writing),
* buffer handling, charsets, and regular expressions.
*/
public class TimeServer {
// The port we'll actually use
private static int port = 8125;
// Charset and encoder for US-ASCII
private static Charset charset = Charset.forName("US-ASCII");
private static CharsetEncoder encoder = charset.newEncoder();
// Direct byte buffer for writing
private static ByteBuffer dbuf = ByteBuffer.allocateDirect(1024);
// Open and bind the server-socket channel
//
private static ServerSocketChannel setup() throws IOException {
ServerSocketChannel ssc = ServerSocketChannel.open();
String host = InetAddress.getLocalHost().getHostAddress();
System.out.println("Listen at Host:" + host + ", port:" + port);
InetSocketAddress isa = new InetSocketAddress(host, port);
ssc.socket().bind(isa);
return ssc;
}
// Service the next request to come in on the given channel
//
private static void serve(ServerSocketChannel ssc) throws IOException {
SocketChannel sc = ssc.accept();
try {
String now = new Date().toString();
sc.write(encoder.encode(CharBuffer.wrap(now + "\r\n")));
System.out.println(sc.socket().getInetAddress() + " : " + now);
sc.close();
} finally {
// Make sure we close the channel (and hence the socket)
sc.close();
}
}
public static void main(String[] args) throws IOException {
if (args.length > 1) {
System.err.println("Usage: java TimeServer [port]");
return;
}
// If the first argument is a string of digits then we take that
// to be the port number
if ((args.length == 1) && Pattern.matches("[0-9]+", args[0]))
port = Integer.parseInt(args[0]);
ServerSocketChannel ssc = setup();
for (;;)
serve(ssc);
}
}
TimeQuery.java充當客戶端,代碼如下所示 -
package com.yiibai;
import java.io.*;
import java.net.*;
import java.nio.*;
import java.nio.channels.*;
import java.nio.charset.*;
import java.util.regex.*;
/* Ask a list of hosts what time it is. Demonstrates NIO socket channels
* (connection and reading), buffer handling, charsets, and regular
* expressions.
*/
public class TimeQuery {
// The port we'll actually use
private static int port = 8125;
// Charset and decoder for US-ASCII
private static Charset charset = Charset.forName("US-ASCII");
private static CharsetDecoder decoder = charset.newDecoder();
// Direct byte buffer for reading
private static ByteBuffer dbuf = ByteBuffer.allocateDirect(1024);
// Ask the given host what time it is
//
private static void query(String host) throws IOException {
InetSocketAddress isa = new InetSocketAddress(InetAddress.getByName(host), port);
SocketChannel sc = null;
try {
// Connect
sc = SocketChannel.open();
sc.connect(isa);
// Read the time from the remote host. For simplicity we assume
// that the time comes back to us in a single packet, so that we
// only need to read once.
dbuf.clear();
sc.read(dbuf);
// Print the remote address and the received time
dbuf.flip();
CharBuffer cb = decoder.decode(dbuf);
System.out.print(isa + " : " + cb);
} finally {
// Make sure we close the channel (and hence the socket)
if (sc != null)
sc.close();
}
}
public static void main(String[] args) throws UnknownHostException {
/**
* if (args.length < 1) { System.err.println("Usage: java TimeQuery
* [port] host..."); return; }
*/
String host = InetAddress.getLocalHost().getHostAddress();
System.out.println("Connect to Host:" + host + ", port:" + port);
try {
query(host);
} catch (IOException x) {
System.err.println(host + ": " + x);
}
}
}
首先運行TimeServer.java,得到以下輸出結果 -
Listen at Host:192.168.0.5, port:8125
然後運行TimeQuery.java從服務器端獲取當前時間,得到以下輸出結果 -
/192.168.0.5:8125 : Fri Sep 29 23:46:55 BOT 2017