欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java网络编程简单了解

程序员文章站 2022-07-10 19:42:34
这篇文章将简单入手Java的HttpURLConnection,InetAddress,Socket以及ServerSocketHttpURLConnectionHttpURLConnection 位于 java.net 包中,提供了用来连接请求URL的方法import java.io.BufferedReader;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;....

这篇文章将简单了解Java的HttpURLConnection,InetAddress,Socket以及ServerSocket

HttpURLConnection

HttpURLConnection 位于 java.net 包中,提供了用来URL连接请求的方法

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @author AhogeK ahogek@gmail.com
 * @date 2021-02-23 16:40
 */
public class HttpUrlConnectionTest {

    public static void main(String[] args) {
        try {
            // 设置一个URL
            URL csdn = new URL("https://www.csdn.net/");
            // 通过设置的URL创建一个HttpURLConnection连接,URL.openConnection()返回的是URLConnection, HttpURLConnection是其子类
            HttpURLConnection httpUrlConnection = (HttpURLConnection) csdn.openConnection();
            // 设置请求的方法,类似还有很多请求配置常用的连接超时等
            httpUrlConnection.setRequestMethod("GET");
            httpUrlConnection.setConnectTimeout(1000);
            // 通过BufferedReader接收响应
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpUrlConnection.getInputStream()));
            // 输出响应内容
            bufferedReader.lines().forEach(System.out::println);
            // 关闭连接与流
            httpUrlConnection.disconnect();
            bufferedReader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

请求成功就能拿到CSDN的首页页面的HTML
Java网络编程简单了解

InetAddress

该类同样在 java.net 包中,用于表示IP地址,例如在socket编程中会用到该类

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * @author AhogeK ahogek@gmail.com
 * @date 2021-02-23 19:51
 */
public class InetAddressTest {

    public static void main(String[] args) throws UnknownHostException {
        /*
         * InetAddress没有公共构造方法,我们可以通过静态方法来构建
         * getByName() 方法可以通过给定主机域名来获取 InetAddress实例
         */
        InetAddress google = InetAddress.getByName("www.google.com");
        // 通过 toString() 可以以 域名/IP 的格式输出
        System.out.println(google.toString());
        // getHostAddress() 用来获取InetAddress对象的IP地址
        System.out.println(google.getHostAddress());
        // getHostName() 即获取其域名
        System.out.println(google.getHostName());
        // 同理也可以反向生成实例对象
        System.out.println(InetAddress.getByAddress("www.google.com",new byte[] {(byte) 172, (byte) 217, 31, (byte) 132}).toString());
        // 输出 本地主机 地址  pc名/本地ip
        System.out.println(InetAddress.getLocalHost());
        // 因为一个域名不一定只映射一个ip,所以 getAllByName 可以获取域名相关连的多个IP
        System.out.println(Arrays.toString(InetAddress.getAllByName("www.google.com")));
    }
}

输出:Java网络编程简单了解

Socket与ServerSocket

Socket

同样位于 java.net,称之为套接字,是作为两台计算机相连的端点

在接下来要写的小demo中,Socket的主要步骤:

  1. 建立与服务器的连接
  2. 使用输出流将数据发送到SockerServer
  3. 使用输入流读取SocketServer返回的数据
  4. 关闭连接

ServerSocket

ServerSocket 是服务端套接字,它会等待Socket的接入,然后执行一系列操作再返回

ServerSocket的主要步骤:

  1. 创建服务器的套接字并将其绑定到特定的接口
  2. 等待客户端Socket的接入
  3. 通过接入的Socket获取其输入流读取数据
  4. 通过接入的Socket获取输出流来写入数据

DEMO

Socket

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.time.LocalDateTime;
import java.util.Scanner;

/**
 * @author AhogeK ahogek@gmail.com
 * @date 2021-02-23 21:01
 */
public class SocketClient {

    public static void main(String[] args) throws IOException {
        System.out.println("Client start!");
        // 创建本地的InetAddress实例 (即用来获取本地服务端IP)
        InetAddress localHost = InetAddress.getLocalHost();
        // 设置服务端端口
        int port = 8080;
        // 用于进行客户端输入的操作
        Scanner clientScanner = new Scanner(System.in);
        // 通过服务器的IP与端口实例化 Socket
        Socket socket = new Socket(localHost.getHostAddress(), port);
        // 实例化 Socket 的输出流 (第二参数指是否自动flush) 用于向服务端写数据
        PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
        // 实例化 Socket 的输入流 用于读取服务端数据
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        LocalDateTime localDateTime = LocalDateTime.now();
        // 除非输入 “exit” 不然不会关闭可以持续输出
        String clientInput;
        while (!"exit".equals(clientInput = clientScanner.nextLine())) {
            // 客户端输入发送至服务器
            writer.println(LocalDateTime.now().toString() + " " + clientInput);
            // 输出服务端返回
            System.out.println("Server: " + br.readLine());
        }
        // 关闭 Socket
        socket.close();
    }
}

ServerSocket

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author AhogeK ahogek@gmail.com
 * @date 2021-02-23 21:15
 */
public class ServerSocketTest {

    private static final int CORE_POOL_SIZE = 5;
    private static final int MAX_POOL_SIZE = 10;
    private static final int QUEUE_CAPACITY = 100;
    private static final Long KEEP_ALIVE_TIME = 1L;
    private final static ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(
            CORE_POOL_SIZE,
            MAX_POOL_SIZE,
            KEEP_ALIVE_TIME,
            TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(QUEUE_CAPACITY),
            new ThreadPoolExecutor.CallerRunsPolicy());

    public static void main(String[] args) throws IOException {
        System.out.println("Server start!");
        // 创建ServerSocket实例
        ServerSocket serverSocket = new ServerSocket(8080);
        // 使用到了Java8的流操作因此这边需要用到原子类
        AtomicBoolean close = new AtomicBoolean(false);
        // 利用这条线程来随时关闭服务器
        EXECUTOR.execute(() -> {
            Scanner scanner = new Scanner(System.in);
           while (!"exit".equals(scanner.nextLine())) {
               close.set(true);
           }
        });
        while (!close.get()) {
            // 支持多线程接入Socket
            EXECUTOR.execute(() -> {
                try {
                    // 调用 accept() 进行阻塞等待 Socket 接入
                    Socket socket = serverSocket.accept();
                    // 接入后获取其输入输出流用于读取写入
                    PrintWriter writer = new PrintWriter(socket.getOutputStream(), true);
                    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    String clientInput;
                    while ((clientInput = reader.readLine()) != null) {
                        System.out.println("client: " + clientInput);
                        // 发回消息给客户端
                        writer.println("This is Server");
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    }
}

输出:
Java网络编程简单了解
Java网络编程简单了解
Java网络编程简单了解
上述代码中,ServerSocket 用了阿里规范中推荐的线程池ThreadPoolExecutor来创建Socket客户端接入的线程

本文地址:https://blog.csdn.net/AhogeK/article/details/113995035

上一篇: Java类加载机制

下一篇: 单词接龙