• Java网络编程


    Java网络编程

    Socket技术

    通过Socket技术(它是计算机之间进行通信一种约定或一种方式),我们就可以实现两台计算机之间的通信

    Socket也被翻译为套接字,是操作系统底层提供的一项通信技术,它支持TCP和UDP

    而Java就对socket底层支持进行了一套完整的封装,我们可以通过Java来实现Socket通信

    //服务端
    public static void main(String[] args) {
        try(ServerSocket server = new ServerSocket(8080)){    //将服务端创建在端口8080上
            System.out.println("正在等待客户端连接...");
            while (true){   //无限循环等待客户端连接
                Socket socket = server.accept();
                System.out.println("客户端已连接,IP地址为:"+socket.getInetAddress().getHostAddress());
            }
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    //客户端
    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 8080)){
            System.out.println("已连接到服务端!");
        }catch (IOException e){
            System.out.println("服务端连接失败!");
            e.printStackTrace();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    一旦TCP连接建立,服务端和客户端之间就可以相互发送数据,直到客户端主动关闭连接。

    Socket进行数据传输

    短链接一收一发:

    public static void main(String[] args) {
        try (Socket socket = new Socket("localhost", 8080);
             Scanner scanner = new Scanner(System.in)){
            System.out.println("已连接到服务端!");
            OutputStream stream = socket.getOutputStream();
            OutputStreamWriter writer = new OutputStreamWriter(stream);  //通过转换流来帮助我们快速写入内容
            System.out.println("请输入要发送给服务端的内容:");
            String text = scanner.nextLine();
            writer.write(text+'\n');   //因为对方是readLine()这里加个换行符
            writer.flush();
            System.out.println("数据已发送:"+text);
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println("收到服务器返回:"+reader.readLine());
            socket.close(); //关闭链接
        }catch (IOException e){
            System.out.println("服务端连接失败!");
            e.printStackTrace();
        }finally {
            System.out.println("客户端断开连接!");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    public static void main(String[] args) {
        try(ServerSocket server = new ServerSocket(8080)){    //将服务端创建在端口8080上
            System.out.println("正在等待客户端连接...");
            Socket socket = server.accept();
            System.out.println("客户端已连接,IP地址为:"+socket.getInetAddress().getHostAddress());
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));  //通过
            System.out.print("接收到客户端数据:");
            System.out.println(reader.readLine());
            OutputStreamWriter writer = new OutputStreamWriter(socket.getOutputStream());
            writer.write("已收到!");
            writer.flush();
            socket.close(); //关闭链接
        }catch (IOException e){
            e.printStackTrace();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    Socket相关使用

    手动关闭单向的流:

    socket.shutdownOutput();  //关闭输出方向的流
    socket.shutdownInput();  //关闭输入方向的流
    
    • 1
    • 2

    设定IO超时时间:

    socket.setSoTimeout(3000);
    
    • 1

    当超过设定时间都依然没有收到客户端或是服务端的数据时,会抛出异常

    链接构造分离方式:

    try (Socket socket = new Socket(); //调用无参构造不会自动连接
         Scanner scanner = new Scanner(System.in)){ 
        socket.connect(new InetSocketAddress("localhost", 8080), 1000);  //手动调用connect方法进行连接
    
    • 1
    • 2
    • 3

    心跳链接检测:

    socket.setKeepAlive(true);
    
    • 1

    如果设置了keeplive为 true,当对方没有发送任何数据过来,超过一个时间(看系统内核参数配置),那么我们这边会发送一个ack探测包发到对方,探测双方的TCP/IP连接是否有效。

    TCP在传输过程中,实际上会有一个缓冲区用于数据的发送和接收,手动调整其大小来优化传输效率:

    socket.setReceiveBufferSize(25565);   //TCP接收缓冲区
    socket.setSendBufferSize(25565);    //TCP发送缓冲区
    
    • 1
    • 2
  • 相关阅读:
    2022最新总结一线大厂Java八股文合集,堪称历史最强
    nvm安装node后,在使用npm指令时候显示不是内部或外部指令
    【Linux】VM及WindowsServer安装
    MariaDB MaxScale实现mysql8读写分离
    记一次在amd架构打包arm64架构的镜像的试错经历
    今天是个好日子,TaxCore(POS软件)备案指北
    TypeScript 泛型类型
    前端静态页面基本开发思路(二)
    Hbase原理与实践(学习笔记一:基本概念):
    Pyhon函数定义中的:必选参数、可选参数、可变参数
  • 原文地址:https://blog.csdn.net/CS_z_jun/article/details/133894019