参考资料: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窗口,并在这些窗口之间切换输入信息。