Java 网络编程基础

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
简介: 一个网络请求、服务之间的调用都需要进行网络通讯,在日常开发时我们可能并不会关心我们的服务端是怎么接收到请求的、调用别的服务是怎么调用的,都是直接使用现成的框架或工具,比如,Tomcat、Dubbo、OkHttp等提供网络服务的框架。作为程序员,我们还是要知其然知其所以然。本文将介绍在 Java 中如何进行网络编程以及网络编程的基础知识。

前言

一个网络请求、服务之间的调用都需要进行网络通讯,在日常开发时我们可能并不会关心我们的服务端是怎么接收到请求的、调用别的服务是怎么调用的,都是直接使用现成的框架或工具,比如,Tomcat、Dubbo、OkHttp等提供网络服务的框架。作为程序员,我们还是要知其然知其所以然。本文将介绍在 Java 中如何进行网络编程以及网络编程的基础知识。

什么是网络编程

网络编程是指利用网络协议和技术实现计算机应用程序之间的通信、数据传输、交换,如TCP/IP协议、HTTP协议、Socket编程等,像 Java、C、C++、Python 这些语言都提供了网络编程的API和库函数,可以便捷地进行网络应用程序的开发。

网络编程基础知识

网络通讯流程

网络通讯过程通常包括以下几个步骤:

  1. 建立连接:通讯双方在网络中建立连接,即在物理层和链路层上进行握手,确认通讯协议和传输参数。

  2. 数据传输:建立连接后,数据可以在通讯双方之间进行传输。数据传输过程中,需要进行分段、封装、逐层封装、加密和校验等。

  3. 数据接收:数据接收方需要先解析、解封装和验证传输数据的正确性,然后对数据进行处理,包括存储和响应等。

  4. 断开连接:在数据传输完成后,通讯双方需要在网络中断开连接,释放资源,并进行必要的后续操作。

长连接和短连接

长连接和短连接是指客户端和服务器端网络连接的不同方式。

长连接指在客户端和服务器端之间建立一条长期保持的连接。一旦建立连接后,客户端和服务器端就可以持续交换数据,而不需要每次发送请求都重新建立连接。长连接通常用于需要频繁交换数据的场合,如在线游戏、聊天室和实时视频等。

短连接指客户端和服务器端之间在完成一次请求后立即断开连接。每次发送请求都需要重新建立连接。短连接通常用于只需要偶尔交换数据的场合,如HTTP请求、电子邮件和浏览网页等。

长连接可以减少连接建立的开销,提高数据传输效率,但可能会浪费一定的网络资源。短连接则可以节省网络资源,但会增加连接建立的开销和数据传输的延迟。

Socket

所谓 Socket (套接字),就是对网络中不同主机上的应用进程之间进行双向通信的抽象。一个套接字就是网络上进程通信的一端,提供了应用层进程利用网络协议交换数据的机制。从所处的地位来讲,套接字上联应用进程,下联网络协议栈,是应用程序通过网络协议进行通信的接口,是应用程序与网络协议栈进行交互的接口。

在这里插入图片描述

Socket 接口把复杂的 TCP/IP 协议族隐藏在后面,对开发人员来讲,通过调用一组接口就可完成网络通信。

Java 网络编程

Java提供了一个强大的网络编程模型和丰富的API来实现网络应用程序,主要基于Socket编程,提供了 ServerSocket 和 Socket 两种Socket,分别用于实现服务器端和客户端。ServerSocket负责绑定IP地址,监听端口,Socket负责发起连接操作。连接成功后,双方通过输入和输出流进行同步阻塞式通信。代码如下:

public class Server {
   
   

    public static void main(String[] args) throws IOException {
   
   
        /*服务器必备*/
        ServerSocket serverSocket = new ServerSocket();
        /*绑定监听端口*/
        serverSocket.bind(new InetSocketAddress(10001));
        System.out.println("Server start.......");

        while(true){
   
   
           //serverSocket.accept()时阻塞,直到接收到客户端的请求
           new Thread(new ServerTask(serverSocket.accept())).start();
        }
    }

    private static class ServerTask implements Runnable{
   
   

        private Socket socket = null;

        public ServerTask(Socket socket) {
   
   
            this.socket = socket;
        }

        @Override
        public void run() {
   
   
            /*socket.getInputStream() 为客户端的输出流*/
            try(
                    ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
                    ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream())
            ){
   
   

                String msg = inputStream.readUTF();
                System.out.println("Accept clinet message:"+msg);
                /*服务器的响应*/
                outputStream.writeUTF("Hello,"+msg);
                outputStream.flush();

            }catch (Exception e){
   
   
                e.printStackTrace();
            }
            finally {
   
   
                try {
   
   
                    socket.close();
                } catch (IOException e) {
   
   
                    e.printStackTrace();
                }
            }

        }
    }
}
public class Client {
   
   

    public static void main(String[] args) throws IOException {
   
   

        Socket socket = null;
        //与服务端通信的输入输出流
        ObjectOutputStream output = null;
        ObjectInputStream input = null;
        //服务器的通信地址
        InetSocketAddress addr = new InetSocketAddress("127.0.0.1",10001);

        try{
   
   
            socket = new Socket();
            /*连接服务器*/
            socket.connect(addr);

            output = new ObjectOutputStream(socket.getOutputStream());
            input = new ObjectInputStream(socket.getInputStream());

            /*向服务器输出请求*/
            output.writeUTF("i‘m Client");
            output.flush();

            //接收服务器的输出
            System.out.println(input.readUTF());
        }finally{
   
   
            if (socket!=null) socket.close();
            if (output!=null) output.close();
            if (input!=null) input.close();

        }
    }
}

以上代码是传统BIO通信模型:采用 BIO 通信模型的服务端,通常由一个独立的 Acceptor 线程负责监听客户端的连接、处理、响应,典型的一请求一应答模型。该模型最大的问题就是缺乏弹性伸缩能力,当客户端并发访问量增加后,线程数量快速膨胀,系统的性能将急剧下降,随着访问量的继续增大,系统最终就会宕机。

总结

对网络编程有所了解后,也就大概知道Tomcat、Dubbo这样的框架最基本的实现原理,拿 Tomcat 举例,无非就是作为服务端监听一个端口,当这个端口有请求时对参数进行接收处理,处理后响应给客户端。当然这种成熟的框架是非常复杂的,有很多细节要考虑,比如数据的序列化问题、性能问题、安全问题、稳定性、扩展性、可靠性等。

相关实践学习
RocketMQ一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
相关文章
|
2月前
|
网络协议 算法 Java
|
3天前
|
网络协议 Java 网络架构
Java基础教程(18)-Java中的网络编程
【4月更文挑战第18天】Java网络编程简化了底层协议处理,利用Java标准库接口进行TCP/IP通信。TCP协议提供可靠传输,常用于HTTP、SMTP等协议;UDP协议则更高效但不保证可靠性。在TCP编程中,ServerSocket用于监听客户端连接,Socket实现双进程间通信。UDP编程中,DatagramSocket处理无连接的数据报文。HTTP编程可以通过HttpURLConnection发送请求并接收响应。
|
11天前
|
监控 Java 开发者
深入理解 Java 网络编程和 NIO
【4月更文挑战第19天】Java网络编程基于Socket,但NIO(非阻塞I/O)提升了效率和性能。NIO特点是非阻塞模式、选择器机制和缓冲区,适合高并发场景。使用NIO涉及通道、选择器和事件处理,优点是高并发、资源利用率和可扩展性,但复杂度、错误处理和性能调优是挑战。开发者应根据需求选择是否使用NIO,并深入理解其原理。
|
13天前
|
网络协议 Java API
深度剖析:Java网络编程中的TCP/IP与HTTP协议实践
【4月更文挑战第17天】Java网络编程重在TCP/IP和HTTP协议的应用。TCP提供可靠数据传输,通过Socket和ServerSocket实现;HTTP用于Web服务,常借助HttpURLConnection或Apache HttpClient。两者结合,构成网络服务基础。Java有多种高级API和框架(如Netty、Spring Boot)简化开发,助力高效、高并发的网络通信。
|
15天前
|
JavaScript Java 测试技术
基于Java的网络游戏交易系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的网络游戏交易系统的设计与实现(源码+lw+部署文档+讲解等)
27 0
|
15天前
|
SQL 安全 Java
Java安全编程:防范网络攻击与漏洞
【4月更文挑战第15天】本文强调了Java安全编程的重要性,包括提高系统安全性、降低维护成本和提升用户体验。针对网络攻击和漏洞,提出了防范措施:使用PreparedStatement防SQL注入,过滤和转义用户输入抵御XSS攻击,添加令牌对抗CSRF,限制文件上传类型和大小以防止恶意文件,避免原生序列化并确保数据完整性。及时更新和修复漏洞是关键。程序员应遵循安全编程规范,保障系统安全。
|
18天前
|
JavaScript Java 测试技术
基于Java的网络游戏交易平台信息管理系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的网络游戏交易平台信息管理系统的设计与实现(源码+lw+部署文档+讲解等)
28 1
|
20天前
|
JavaScript Java 测试技术
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
31 0
基于Java的网络类课程思政学习系统的设计与实现(源码+lw+部署文档+讲解等)
|
28天前
|
网络协议 安全 Java
Java网络编程实战:构建高效稳定的网络通信
【4月更文挑战第2天】Java网络编程涉及Socket编程,基于TCP(可靠,面向连接)和UDP(不可靠,无连接)协议。Socket类和ServerSocket类用于TCP,而DatagramSocket和DatagramPacket处理UDP。高效通信涉及线程管理、选择合适的IO模型(如NIO)、利用缓冲区及确保网络安全,如使用SSL/TLS。适用于Web服务器、文件传输等场景。
Java网络编程实战:构建高效稳定的网络通信
|
2月前
|
JSON Java 网络安全
Java使用hutool工具类发送网络请求
Java使用hutool工具类发送网络请求
44 0