在本示例中,实现时间服务器。服务器监听连接,并向连接的客户端发送当前服务器的时间。这是一个简单的阻塞程序,演示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