Java网络编程

Posted by Wh0ami-hy on July 5, 2021

1. 网络通信的要素

  • ip:端口
  • 网络通信协议

    2. 网络通信的两种模型

2.1. C/S

一套程序为客户端,另外一套程序为服务器端

这种开发可以由开发者自定义传输协议,并且使用一些比较私密的端口

所以安全性是比较高的,但是开发与维护成本比较高

其分为两种开发:TCP(可靠的数据连接)、UDP(不可靠的数据连接)

2.2. B/S

只开发一套服务器端的程序,使用的是公共的HTTP协议并且使用的公共的 80 端口,所以其安全性相对较差

3. TCP通信

使用两个类实现数据的交互处理:ServerSocket (服务器端)、Socket(客户端)

3.1. ServerSocket

public class Server {
    public static void main(String[] args) throws Exception {
        // 实例化一个 ServerSocket 对象
        ServerSocket server = new ServerSocket(888);
        System.out.println("listening......");
        // 监听端口,等待客户端连接
        Socket client = server.accept();
        // 接收客户端的输入流
        Scanner scan = new Scanner(client.getInputStream());
        // 向客户端发送数据
        PrintStream out = new PrintStream(client.getOutputStream());
        boolean flag = true;
        while (flag){
            // 如果接收到客户端的信息
            if (scan.hasNext()){
                String val = scan.next();
                if ("stop".equals(val)){
                    out.println("stop server!!!");
                    flag = false;
                }else {
                    // 向客户端返回数据
                    out.println("【echo】" + val);
                }
            }
        }
        server.close();
        scan.close();
        out.close();
        client.close();
    }
}

3.2. Socket

public class Socket {
    // 接收键盘的输入内容
    public static Scanner keyboard = new Scanner(System.in);
    public static void main(String[] args) throws Exception {
        // 连接服务器
        Socket client = new Socket("localhost", 888);
        // 接收服务器端的输入流
        Scanner scan = new Scanner(client.getInputStream());
        // 向服务器端发送内容
        PrintStream out = new PrintStream(client.getOutputStream());
        boolean flag = true;
        while (flag){
            String input = getString("【input content】");
            out.println(input);
            // 如果服务器端有响应
            if (scan.hasNext()){
                System.out.println(scan.next());
            }
            // 如果输入 stop 就停止
            if ("stop".equals(input)){
                flag = false;
            }
        }
        client.close();
        out.close();
        scan.close();
        keyboard.close();
    }
    // 接收键盘的输入
    public static String getString(String prompt) throws Exception{
        System.out.println(prompt);
        String str = keyboard.next();
        return str;
    }
}

连接建立后,通过 I/O 流进行通信,每一个socket都有一个输出流和一个输入流,客户端的输出流连接到服务器端的输入流,而客户端的输入流连接到服务器端的输出流。

TCP 是一个双向的通信协议,因此数据可以通过两个数据流在同一时间发送。

4. UDP通信

实现UDP程序需要两个类:DatagramPacket(数据内容)、DatagramSocket (网络发送与接收) 数据报的发送:客户端是否接收到与发送者无关

4.1. 客户端

public class UDPClient {
    public static void main(String[] args) throws Exception {
        // 客户端接收信息的端口
        DatagramSocket client = new DatagramSocket(888);
        byte[] data = new byte[1024];
        DatagramPacket packet = new DatagramPacket(data,data.length);
        System.out.println("waiting accept content...");
        // 接收消息
        client.receive(packet);
        System.out.println("【accepted content】" + new String(data,0,packet.getLength()));
        client.close();
    }
}

4.2. 服务端

public class UDPServer {
    public static void main(String[] args) throws Exception {
        // 服务端发送信息的端口
        DatagramSocket server = new DatagramSocket(88);
        String str = "www.baidu.com";
        // 发送数据
        DatagramPacket packet = new DatagramPacket(str.getBytes(),0,str.length(), InetAddress.getByName("localhost"),888);
        server.send(packet);
        System.out.println("message sended");
        server.close();
    }
}

5. URL下载网络资源

public class demo {
    public static void main(String[] args) throws Exception {
        // 资源地址
        URL url = new URL("https://img1.wallspic.com/previews/8/8/9/1/7/171988/171988-genshin_impact_ling_xiang_nu_pu-hoyolab-ka_tong-bai_se-zi_se_de-x750.jpg");
        // 连接资源
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        // 请求资源
        InputStream inputStream = urlConnection.getInputStream();
        // 设置文件
        FileOutputStream fos = new FileOutputStream("test.jpg");
        // 临时缓存
        byte[] buffer = new byte[1024];
        int len;
        while ((len=inputStream.read(buffer)) != -1){
            // 将请求得到的数据写入文件
            fos.write(buffer,0,len);
        }
        // 关闭IO
        fos.close();
        inputStream.close();
        urlConnection.disconnect();
    }
}

本站总访问量