使用Socket
Socket是两台主机之间的一个连接,它可以完成7个操作。
- 连接远程机器
- 发送数据
- 接收数据
- 关闭连接
- 绑定端口
- 监听入站数据
- 在绑定端口上接受来自远程机器的连接
Java中的Socket类提供了对应前4个操作方法,后面的3个操作仅服务器需要,即等待客户端的连接。一旦连接建立,本地和远程主机就从这个socket得到输入流和输出流,使用这两个流可以相互发送数据。
读取服务器数据
欲连接的服务器是时间服务器(NTP),下面是通过Telnet来从时间服务器获取当前时间
通过Telnet连接到NTP服务器(time.nist.gov,该服务器在美国)的13端口,对方返回当前的格林威治时间,使用的协议的daytime协议,该协议在RFC867中有详细说明。下面通过JAVA程序来获取当前时间。
public static void main(String[] args) {
try (Socket socket = new Socket("time.nist.gov", 13)) {
socket.setSoTimeout(15000);
InputStreamReader reader = new InputStreamReader(socket.getInputStream(), "ASCII");
StringBuilder sb = new StringBuilder();
for (int c = reader.read(); c!=-1; c=reader.read())
sb.append((char)c);
Date date = parseDate(sb.toString());
System.out.println(date);
} catch (Exception e) {
e.printStackTrace();
}
}
static Date parseDate(String s) throws ParseException {
String[] pieces = s.split(" ");
String dateTime = pieces[1] + " " + pieces[2] + " UTC";
DateFormat format = new SimpleDateFormat("yy-MM-dd hh:mm:ss z");
return format.parse(dateTime);
}
通过上面代码执行后输出的是本地时间,因为JAVA会自动帮我们进行时区转换(时区的设置和JVM虚拟的有关)。
半关闭Socket
close()方法会直接关闭Socket。有时希望只关闭连接的一半,即输入或者输出,可以使用下面两个方法:
public void shutdownInput()
public void shutdownOutput()
这两个方法并不会关闭Socket。实际上它会调整与Socket连接的流,使它认为已经到了流的,它不会在发送数据或接收数据。关闭输入之后再读取输入流会返回-1,关闭输出流之后再向Socket写入数据会抛出一个IOException异常。