Java网络编程小案例

  • 一、Java网络工具包简介
  • 二、InetAddress
  • 三、InetSocketAddress
  • 四、URL类
  • 五、Socket


一、Java网络工具包简介


Java为了可移植性,不允许直接调用操作系统,而是由包来提供网络功能。Java虚拟机负责提供与操作系统的实际连接。下面我们来介绍几个包中的常用的类。

二、InetAddress


  • 作用
    封装计算机的IP地址和DNS(Domain Name System)但不封装端口信息。
  • 特点
    这个类没有构造方法。如果要得到对象,只能通过静态方法去创建。
  • 案例
  • 案例一 :使用getLocalHost方法创建InetAddress对象
import .InetAddress;
import .UnknownHostException;
public class Test1 {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress addr = InetAddress.getLocalHost();
        //返回IP地址:如192.168.1.110
        System.out.println(addr.getHostAddress()); 
        //输出计算机名:suben
        System.out.println(addr.getHostName());     
    }
}
  • 案例二:根据域名得到InetAddress对象
import .InetAddress;
import .UnknownHostException;
public class Test2 {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress addr = InetAddress.getByName("www.sujiangming.com.cn");
        // 返回服务器的IP:120.79.234.144
        System.out.println(addr.getHostAddress());
        // 输出:www.sujiangming.com.cn
        System.out.println(addr.getHostName());
    }
}
  • 案例三:根据IP得到InetAddress对象
import .InetAddress;
import .UnknownHostException;
public class Test3 {
    public static void main(String[] args) throws UnknownHostException {
        InetAddress addr = InetAddress.getByName("120.79.234.144");
        // 返回服务器的IP:120.79.234.144
        System.out.println(addr.getHostAddress());
        /*
         * 输出ip而不是域名。如果这个IP地址不存在或DNS服务器不允许进行IP地址
         * 和域名的映射,getHostName方法就直接返回这个IP地址。
         */
        System.out.println(addr.getHostName());
    }
}

三、InetSocketAddress


  • 作用:
    包含IP和端口信息,常用于Socket通信。此类实现 IP 套接字地址(IP 地址 + 端口号),不依赖任何协议。
  • 案例:InetSocketAddress的使用
import .InetSocketAddress;
public class Test4 {
    public static void main(String[] args) {
        InetSocketAddress socketAddress = new InetSocketAddress("127.0.0.1", 8080);
        InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 9000);
        System.out.println(socketAddress.getHostName());
        System.out.println(socketAddress2.getAddress());
    }
}

四、URL类


  • 作用:
    URL 类 代表一个统一资源定位符,它是指向互联网“资源”的指针。资源可以是简单的文件或目录,也可以是对更为复杂的对象的引用,例如对数据库或搜索引擎的查询。
  • 案例:
  • 案例一:URL类的使用
import .MalformedURLException;
import .URL;
public class Test5 {
    public static void main(String[] args) throws MalformedURLException {
        URL u = new URL("http://www.google.cn:80/webhp#aa?canhu=33");
        System.out.println("获取与此url关联的协议的默认端口:" + u.getDefaultPort());
        System.out.println("getFile:" + u.getFile()); // 端口号后面的内容
        System.out.println("主机名:" + u.getHost()); // www.google.cn
        System.out.println("路径:" + u.getPath()); // 端口号后,参数前的内容
        // 如果www.google.cn:80则返回80.否则返回-1
        System.out.println("端口:" + u.getPort()); 
        System.out.println("协议:" + u.getProtocol());
        System.out.println("参数部分:" + u.getQuery());
        System.out.println("锚点:" + u.getRef());
 
        URL u1 = new URL("http:///aa/");
        URL u2 = new URL(u, "2.html"); // 相对路径构建url对象
        System.out.println(u2.toString()); // http:///aa/2.html
    }
}
  • 案例二:最简单的网络爬虫
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import .MalformedURLException;
import .URL;
 
public class Test6 {
    public static void main(String[] args) {
        basicSpider();
    }
    //网络爬虫
    static void basicSpider() {
        URL url = null;
        InputStream is = null;
        BufferedReader br = null;
        StringBuilder sb = new StringBuilder();
        String temp = "";
        try {
            url = new URL("http://www.baidu.com");
            is = url.openStream();
            br = new BufferedReader(new InputStreamReader(is));
            /* 
             * 这样就可以将网络内容下载到本地机器。
             * 然后进行数据分析,建立索引。这也是搜索引擎的第一步。
             */
            while ((temp = br.readLine()) != null) {
                sb.append(temp);
            }
            System.out.println(sb);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

五、Socket


  • 概念
    套接字是一种进程间的数据交换机制。
  • 作用
    套接字起到通信端点的作用。单个套接字是一个端点,而一对套接字则构成一个双向通信信道,使非关联进程可以在本地或通过网络进行数据交换。
  • C/S(请求-响应)
  • Client客户端
    Socket类:发送TCP消息
  • Server端
    ServerSocket类:创建服务器
  • 通信机制
    1、Client和Server都需要定义好Socket对象
    2、让Socket进行建立连接
    3、发送数据
  • 编程思路及顺序
  1. 创建服务器ServerSocket,在创建时,定义ServerSocket的监听端口(在这个端口接收客户端发来的消息)。
  2. ServerSocket调用accept()方法,使之处于阻塞状态。
  3. 创建客户端Socket,并设置服务器的IP及端口。
  4. 客户端发出连接请求,建立连接。
  5. 分别取得服务器和客户端Socket的InputStream和OutputStream。
  6. 利用Socket和ServerSocket进行数据传输。
  7. 关闭流及Socket
  • 案例说明: 运行时,要先启动服务器端,再启动客户端,才能得到正常的运行效果。
  • 案例一:单向通信Socket之服务器端
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import .ServerSocket;
import .Socket;
 
/**
 * 最简单的服务器端代码
 * @author Administrator
 */
public class BasicSocketServer {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedWriter bw = null;
        try {
            // 建立服务器端套接字:指定监听的接口
            ServerSocket serverSocket = new ServerSocket(8888);
            System.out.println("服务端建立监听");
            // 监听,等待客户端请求,并愿意接收连接
            socket = serverSocket.accept();
            // 获取socket的输出流,并使用缓冲流进行包装
            bw = new BufferedWriter(new     
                                    OutputStreamWriter(socket.getOutputStream()));
            // 向客户端发送反馈信息
            bw.write("hhhh");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭流及socket连接
            if (bw != null) {
                try {
                    bw.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 案例二:单向通信Socket之客户端
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import .InetAddress;
import .Socket;
/**
 * 最简单的Socket客户端
 * @author Administrator
 */
public class BasicSocketClient {
    public static void main(String[] args) {
        Socket socket = null;
        BufferedReader br = null;
        try {
            /*
             * 创建Scoket对象:指定要连接的服务器的IP和端口而不是自己机器的
             * 端口。发送端口是随机的。
             */
            socket = new Socket(InetAddress.getLocalHost(), 8888);
            //获取scoket的输入流,并使用缓冲流进行包装
            br = new BufferedReader(new  
                                   InputStreamReader(socket.getInputStream()));
            //接收服务器端发送的信息
            System.out.println(br.readLine());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭流及socket连接
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (socket != null) {
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
  • 案例三:双向通信Socket之服务器端
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import .ServerSocket;
import .Socket;
 
public class Server {
    public static void main(String[] args){
        Socket socket = null;
        BufferedReader in = null;
        BufferedWriter out = null;
        BufferedReader br = null;
        try {
            //创建服务器端套接字:指定监听端口
            ServerSocket server = new ServerSocket(8888);
            //监听客户端的连接
            socket = server.accept();
            //获取socket的输入输出流接收和发送信息
            in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            out = new BufferedWriter(new 
                                   OutputStreamWriter(socket.getOutputStream()));
            br = new BufferedReader(new InputStreamReader(System.in));
            while (true) {
                //接收客户端发送的信息
                String str = in.readLine();
                System.out.println("客户端说:" + str);
                String str2 = "";
                //如果客户端发送的是“end”则终止连接 
                if (str.equals("end")){
                    break;
                }
                //否则,发送反馈信息
                str2 = br.readLine(); // 读到\n为止,因此一定要输入换行符!
                out.write(str2 + "\n");
                out.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            if(in != null){
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(out != null){
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(br != null){
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket != null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}