参考资料:Java核心技术 卷II
1. 使用Telent工具连接到服务器
打开Telnet:电脑右键,选择属性->控制面板主页->程序->打开或关闭Windows功能,在弹出的窗口中选择Telnet客户端。
cmd打开命令行窗口,
方法一:输入:
telnet time-A.timefreq.bldrdoc.gov 13
方法二:
首先在命令窗中输入:telnet,再在弹出的Telnet窗口中输入:
o time-A.timefreq.bldrdoc.gov 13
结果为:
说明已经连接到了大多数UNIX计算机都支持的“当日时间”服务。按照惯例,“当日时间”服务总是连接到端口13.
下面的java实现与使用Telnet工具是一致的,即连接到某个端口并打印它所找到的信息。
public class SocketTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
Socket s = new Socket("time-A.timefreq.bldrdoc.gov", 13);//打开一个套接字
s.setSoTimeout(1000);//套接字超时设置
try{
InputStream inStream = s.getInputStream();//返回此套接字的输入流
Scanner in = new Scanner(inStream);//获取流中的数据
while(in.hasNextLine()){//输出流中的数据
String line = in.nextLine();
System.out.println(line);
}
}
catch(InterruptedIOException exception){//获取超时异常
exception.printStackTrace();
}
finally{
s.close();//关闭此套接字
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
2. 获取IP地址
下面的java代码获取主机的IP地址。如果指定了主机名,将打印出给定主机的IP地址;如果没有指定主机,则打印出本地主机的IP地址。
可在Run->Run Configurations->Arguments->Program arguments中,设置给定的主机名。设置好后,点击apply->run.
public class InetAddressTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
if(args.length > 0){//获取从外部输入的主机名
String host = args[0];
/**
* static InetAddress getByName(String host)方法: 返回给定主机的IP地址
* static InetAddress getAllByName(String host)方法:返回给定主机所对应的所有IP地址组成的数组
*/
InetAddress[] addresses = InetAddress.getAllByName(host);
for(InetAddress a : addresses)
System.out.println(a);
}
else{
//static InetAddress getLocalHost() 返回本地主机
InetAddress localHostAddress = InetAddress.getLocalHost();
System.out.println(localHostAddress);
//byte[] getAddress() 返回此InetAddress对象的原始IP地址(byte数组形式)
byte[] addressByte = localHostAddress.getAddress();
System.out.println(addressByte);
//String getHostAddress() 返回字符串形式的IP地址
String addressInte = localHostAddress.getHostAddress();
System.out.println(addressInte);
//String getHostName() 返回主机名
String localHostName = localHostAddress.getHostName();
System.out.println(localHostName);
}
}
catch(Exception e){
e.printStackTrace();
}
}
3. 实现服务器
实现一个简单的服务器,它可以向客户端发送消息。一旦启动服务器程序,它就等待某个客户端连接到它的端口。这里选择的端口是8189. java实现:
public class EchoServer {
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
ServerSocket s = new ServerSocket(8189);// /建立一个负责监控8189端口的服务器
Socket incoming = s.accept();//一旦客户端向该端口发送了正确的连接请求,该方法就返回一个表示连接已经建立的Socket对象,可以用这个对象来得到输入流和输出流
try{
InputStream inStream = incoming.getInputStream(); //用于得到服务器的输入流
OutputStream outStream = incoming.getOutputStream();//用于得到服务器的输出流
Scanner in = new Scanner(inStream);//将服务器的输入流转换成扫描器
PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);//将服务器的输出流转换成写入器
out.println("Hello, Enter BYE to exit."); //给客户端发送一条问候信息
boolean done = false;
while(!done && in.hasNextLine()){
String line = in.nextLine();//得到客户端的输入流
out.println("Echo: " + line);//客户端的输出流
if(line.trim().equals("BYE"))//当客户端输入为BYE时,退出
done = true;
}
}
finally{
incoming.close();//关闭连接进来的套接字
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
运行:点击运行,再在命令行窗口输入:
telnet localhost 8189 //或telnet 127.0.0.1 8189
4. 为多个客户端服务
利用线程解决多个客户端同时连接到服务器的问题。每当程序建立一个新的套接字连接,即成功调用accept()方法的时候,将创建一个新的线程来处理服务器和该客户端之间的连接,而主程序将立即返回并等待下一个连接。java实现:
public class ThreadedEchoServer {
public static void main(String[] args) {
// TODO Auto-generated method stub
try{
int i = 1;
ServerSocket s = new ServerSocket(8189);
while(true){//多个客户端
Socket incoming = s.accept();
System.out.println("spawning " + i); //在服务器端的输出。
Runnable r = new ThreadedEchoHandler(incoming);
Thread t = new Thread(r);//创建一个线程
t.start();
i++;
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
/*
* 实现Runnable接口的run 方法。
*/
class ThreadedEchoHandler implements Runnable{
private Socket incoming;
public ThreadedEchoHandler(Socket i){
incoming = i;
}
public void run() {
// TODO Auto-generated method stub
try{
try{
InputStream inStream = incoming.getInputStream();
OutputStream outStream = incoming.getOutputStream();
Scanner in = new Scanner(inStream);
PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);
out.println("Hello! Enter BYE to exit");
boolean done = false;
while(!done && in.hasNextLine()){
String line = in.nextLine();
out.println("echo: " + line);
if(line.trim().equals("BYE"))
done = true;
}
}
finally{
incoming.close();
}
}
catch(IOException e){
e.printStackTrace();
}
}
}
运行结果:可打开多个Telnet窗口,并在这些窗口之间切换输入信息。