16 Java网络编程(计算机网络+网络模型OSI/TCP/IP+通信协议等)

本文涉及的产品
.cn 域名,1个 12个月
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 16 Java网络编程(计算机网络+网络模型OSI/TCP/IP+通信协议等)

16.1 网络概述


16.1.1 概念

由点和线构成,表示诸多对象间的相互联系。

16.1.2 计算机网络

为实现资源共享和信息传递,通过通信线路连接起来的若干主机(Host)。

常见计算机网络:

  • 互联网:(Internet)点与点相连。
  • 万维网:(WWW – World Wide Web)端与端相连。
  • 物联网:( IoT - Internet of things) 物与物相连。
  • 网络编程:让计算机与计算机之间建立连接、进行通信。

16.1.3 网络模型

16.1.3.1 OSI参考模型

OSI(Open System Interconnect),即开放式系统互联。

  • 是ISO组织在1985年研究的网络互联模型。

每层功能:

  • 第七层:应用层负责文件访问和管理、可靠运输服务、远程操作服务。(HTTP、FTP、SMTP)。
  • 第六层:表示层负责定义转换数据格式及加密,允许选择以二进制或ASCII格式传输。
  • 第五层:会话层负责使应用建立和维持会话,使通信在失效时继续恢复通信。(断点续传)。
  • 第四层:传输层负责是否选择差错恢复协议、数据流重用、错误顺序重排。(TCP、UDP)。
  • 第三层:网络层负责定义了能够标识所有网络节点的逻辑地址。(IP地址)。
  • 第二层:链路层在物理层上,通过规程或协议(差错控制)来控制传输数据的正确性。(MAC)。
  • 第一层:物理层为设备之间的数据通信提供传输信号和物理介质。(双绞线、光导纤维)。
16.1.3.2 TCP/IP模型
  • TCP/IP模型是因特网使用的参考模型,基于TCP/IP的参考模型将协议分成四个层次。
  • 该模型中最重要的两个协议是TCP和IP协议

每层功能:

  • 第四层:应用层负责传送各种最终形态的数据,是直接与用户打交道的层,典型协议是HTTP、FTP等。
  • 第三层:传输层负责传送文本数据,主要协议是TCP、UDP协议。
  • 第二层:网络层负责分配地址和传送二进制数据,主要协议是IP协议。
  • 第一层:接口层负责建立电路连接,是整个网络的物理基础,典型的协议包括以太网、ADSL等等。

16.1.4 网络编程总结

  1. 计算机网络:为实现资源共享、信息传递通过传出介质将若干台主机连接到一起的一个网络
  2. 计算机网络模型:

OSI

应用层 主要指的是程序
表示层 讲数据加密或者解密成二进制的数据
会话层 保持主机之间的连接
传输层 通过网络协议传输数据(TCP协议、UDP协议)
网络层 分配IP地址(IP地址)
网络数据链路层 保证准确性(MAC地址物理地址)
物理层 进行数据传输

  • TCP/IP
应用层
传输层
网络层
物理层

  1. 网络编程需要什么【重点 】
  1. 通信协议(TCP\UDP\HTTP)
  2. IP地址
  3. 端口号

网络编程三要素:协议、地址、端口号

16.2 常见协议

16.2.1 IP协议概述

IP协议:Internet Protocol Address 互联网协议地址/网际协议地址:

  • 分配给互联网设备的数字标签(唯一标识)。

IP地址版本:

  • IPV4:4字节32位整数,并分成4段8位的二进制数,每8位之间用圆点隔开,每8位整数可以转换为一个0~255的十进制整数。
    格式:D.D.D.D 例如:255.255.255.255
  • IPV6:16字节128位整数,并分成8段十六进制数,每16位之间用圆点隔开,每16位整数可以转换为一个0~65535的十进制数。
    格式:X.X.X.X.X.X.X.X 例如:FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF

IP地址分类:

A类地址 大型网络:网络地址.主机地址.主机地址.主机地址

B类地址 中型网络:网络地址.网络地址.主机地址.主机地址

C类地址 个人网络:网络地址.网络地址.网络地址.主机地址

A类:政府机构,1.0.0.1 ~ 126.255.255.254

B类:中型企业,128.0.0.1 ~ 191.255.255.254

C类:个人用户,192.0.0.1 ~ 223.255.255.254

D类:用于组播,224.0.0.1 ~ 239.255.255.254

E类:用于实验,240.0.0.1 ~ 255.255.255.254

  • 回环地址:127.0.0.1,指本机,一般用于测试使用。

查看IP命令:ipconfig

测试IP命令:ping D.D.D.D

/**
 * 网络三要素之ip地址
 * 1、概念
 *   a、什么是IP地址  (了解)
 *      分配给每一台主机的唯一数字标识
 *
 *   b、ipv4和ipv6  (了解)
 *      ipv4:4个字节32位组成,每一段由8位组成。使用0~255之间的数字表示(应用)
 *      ipv6:16个字节128位组成,每一段由32位组成。使用0~65535之间的数字表示
 *   c、ip地址的分类
A类地址     大型网络:网络地址.主机地址.主机地址.主机地址
B类地址     中型网络:网络地址.网络地址.主机地址.主机地址
C类地址     个人网络:网络地址.网络地址.网络地址.主机地址
 *   d、回路地址(自己与自己通信IP地址)  (重要)
 *                     域名
 *      127.0.0.1     localhost
 *
 *      DNS域名解析器:将域名解析成ip地址。一个ip地址可以对应多个域名  一个域名职能对应一个ip地址
 *      默认情况下:DNS解析回去找到C:\Windows\System32\drivers\etc\hosts文件去查找对应的域名解析,
 *                 如果找不到会去DNS服务器中取查找
 *      常见的DNS域名器:114.114.114.114   8.8.8.8
 *
 *    e、ip相关的命令    (重要)
 *      ipconfig(查看本机的ip地址信息)   ifconfig(Linux操作系统,查看本机的ip地址信息)
 *      ping命令 (检查是否连接上了目标主机)
 *
 *      https://www.baidu.com:80/
 *
 * 2、应用
 *      java是面向对象的编程语言,在java使用InetAddress类表示ip地址信息
 */

16.2.2 InetAddress类

概念:表示互联网协议(IP)地址对象,封装了与该IP地址相关的所有信息,并提供获取信息的常用方法。

常见方法:

方法名 描述
public static InetAddress getLocalHost() 获得本地主机地址对象
public static InetAddress getByName(String host) 根据主机名称获得地址对象
public static InetAddress[] getAllByName(String host) 获得所有相关地址对象
public String getHostAddress() 获取IP地址字符串
public String getHostName() 获得IP地址主机名
public class TestIP {
/**
 *
 *  //方式一:获取本机的InetAddress对象
 *         //通过本地的ip地址信息获取InetAddress对象
 *         InetAddress ia = InetAddress.getLocalHost();
 *         //InetAddress对象的常用方法
 *         //获取主机名(域名)
 *         String hostName = ia.getHostName();
 *         System.out.println(hostName);
 *         //获取ip地址
 *         String hostAddress = ia.getHostAddress();
 *         System.out.println(hostAddress);
 *  //方式二:根据指定的主机名获取InetAddress对象
 *         InetAddress ia = InetAddress.getByName("www.baidu.com");
 *         //InetAddress对象的常用方法
 *         String hostName = ia.getHostName();
 *         System.out.println(hostName);
 *         String hostAddress = ia.getHostAddress();
 *         System.out.println(hostAddress);
 *  //方式三:根据指定的ip地址获取InetAddress对象
 *          InetAddress ia = InetAddress.getByName("14.215.177.38");
 *          System.out.println(ia.getHostName());
 *          System.out.println(ia.getHostAddress());
 */
    public static void main(String[] args) throws UnknownHostException {
        //创建InetAddress对象
        //方式四:根据指定的主机名获取所有的InetAddress
        InetAddress[] ias = InetAddress.getAllByName("www.baidu.com");
        //使用lambda表达式遍历
        /*Arrays.stream(ias).forEach(ia ->{
            System.out.println(ia.getHostAddress());
            System.out.println(ia.getHostName());
        });*/
        //使用foreach循环遍历
        for (InetAddress ia : ias) {
            System.out.println(ia.getHostAddress());
            System.out.println(ia.getHostName());
        }
    }
}

16.3 端口号

16.3.1 端口号概述

端口号:在通信实体上进行网络通讯的程序的唯一标识。

端口分类(端口的范围:0~65535之间):

  • 公认端口:0~1023
  • 注册端口:1024~49151
  • 动态或私有端口:49152~65535 (指的是程序没有设置端口号系统默认随机分配的端口号)

常用端口号:

  • MySql:3306
  • Oracle:1521
  • redis:6379
  • Tomcat:8080
  • SMTP:25
  • Web服务器:80
  • FTP服务器:21

注意:以后自己编写的程序的端口号最好设置在1024~65535之间即可

16.4 通信协议

16.4.1 通信协议概述

  1. 概念:
    TCP:传输控制协议
特点:面向连接、安全可靠、效率低、基于字节流进行通信、数据大小无限制。
建立连接三次握手、断开连接四次挥手
 
通俗解释:打电话

UDP:数据报协议

特点:面向无连接、不安全、效率高、基于数据报包的形式通信、数据包大概在64kb

在java中使用Socket类来进行网络编程
Socket:套接字、指的是网络间的一个通信设备

2.基于TCP协议进行通信

  • 案例:客户端发送消息,服务端进行接收
  • 案例: 客户端通过Scanner录入数据发送消息。服务端进行使用多线程接收
  • 案例:客户端上传图片到服务端,服务端发送数据到客户端

3.基于UDP协议进行通信

  • 案例:发送端发送消息,接收端进行接收
  • 案例:使用udp协议给飞秋发送数据

16.5 基于TCP协议通信

Socket编程:

  • Socket(套接字)是网络中的一个通信节点。
  • 分为客户端Socket与服务器ServerSocket。
  • 通信要求:IP地址 + 端口号。

开发步骤:

  • 建立通信连接(会话):
  • 创建ServerSocket,指定端口号。
  • 调用accept等待客户端接入。
  • 客户端请求服务器:
  • 创建Socket,指定服务器IP + 端口号。
  • 使用输出流,发送请求数据给服务器。
  • 使用输入流,接收响应数据到客户端(等待)
  • 服务器响应客户端。
  • 使用输入流,接收请求数据到服务器(等待)。
  • 使用输出流,发送响应数据给客户端。

16.5.1 案例1

通过客户端向服务端发送信息

/**
 * 客户端程序
 */
public class Client {
    public static void main(String[] args) throws IOException {
        //1、创建客户端Socket对象
        Socket socket = new Socket("127.0.0.1",6666);
        //2、通过Socket对象获取输出流对象
        OutputStream out = socket.getOutputStream();
        //3、通过输出流对象写出数据
        //将字符串转换成字节数组   字符串.getBytes("字符集");
        out.write("hello,我是客户端!!!".getBytes());
        //4、关闭资源
        out.close();
        socket.close();
    }
}
/**
 * 服务端程序
 */
public class Server {
    public static void main(String[] args) throws IOException {
        //1、创建服务端端Socket对象
        ServerSocket ss = new ServerSocket(6666);
        //2、通过ServerSocket对象获取Socket对象
        //ss.accept()阻塞式方法。直到有客户端与之建立连接才会继续向下执行
        Socket socket = ss.accept();
        //3、通过Socket对象获取输入流对象
        InputStream in = socket.getInputStream();
        //4、通过输入流对象读出数据
        int len; //表示读取到的字节的长度
        byte[] buf = new byte[1024]; // 表示缓冲区
        while((len = in.read(buf)) != -1){
            //将字节数组转转成字符串
            String str = new String(buf,0,len);
            System.out.println(str);
        }
        //5、关闭资源
        in.close();
        socket.close();
        ss.close();
    }
}

16.5.2 案例2

基于多线程实现客户端服务端通信

/**
 * 客户端程序
 */
public class Client {
    public static void main(String[] args) throws IOException {
        //创建Scanner对象
        Scanner sc = new Scanner(System.in);
       while(true){
           //1、创建客户端Socket对象
           Socket socket = new Socket("localhost",6677);
           //2、获取输出流对象
           OutputStream out = socket.getOutputStream();
           //3、通过输出流对象写出数据
           //获取输入的内容  next():用于获取输入的字符串(以空格为标记进行获取)   nextLine():用于获取输入的字符串(以回车为标记进行获取)
           String words = sc.next();
           if("886".equals(words)||"over".equals(words)){
               //4、释放资源
               out.close();
               socket.close();
               break;
           }
           out.write(words.getBytes());
           //4、释放资源
           out.close();
           socket.close();
       }
    }
}
 
/**
 * 服务端程序
 */
public class Server {
    public static void main(String[] args) throws IOException {
        //1、创建服务端Socket对象
        ServerSocket ss = new ServerSocket(6677);
        System.out.println("服务端已开启等待客户端连接....");
        while(true){
            //2、获取Socket对象
            Socket socket = ss.accept();
            //获取客户端发送的信息
            String ip = socket.getInetAddress().getHostAddress();
            //创建线程来处理客户端的请求
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        //3、通过Socket对象获取输入流
                        InputStream in = socket.getInputStream();
                        //4、通过输入流读取内容
                        BufferedReader br = new BufferedReader(new InputStreamReader(in));
                        String readLine = br.readLine();
                        System.out.println(ip+":"+readLine);
                        //5、释放资源
                        in.close();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

16.5.3 案例3

实现客户端文件上传功能,并从服务端向客户端发送数据

/**
 * 客户端程序
 */
public class Client {
    //客户端向服务端发送图片
    public static void main(String[] args) throws IOException {
        //1、创建Socket对象
        Socket socket = new Socket("192.168.73.210",8899);
        //2、通过Socket获取输出流对象
        OutputStream out = socket.getOutputStream();
        //思路:从本地将图片读取出来,然后通过socket输出流立马写出去
        FileInputStream fis = new FileInputStream("d:\\41.jpg");
        byte[] buf = new byte[1024];
        int len;
        while((len = fis.read(buf))!=-1){
            //3、通过输出流写出数据
            out.write(buf,0,len);
        }
        //告知服务器这边已经写完了
        socket.shutdownOutput();

        //从服务端接收到返回信息
        InputStream in = socket.getInputStream();
        BufferedReader br =  new BufferedReader(new InputStreamReader(in));
        System.out.println(br.readLine());


        //4、释放资源
        in.close();
        fis.close();
        out.close();
        socket.close();
    }
}
/**
 * 服务端程序
 */
public class Server {

    public static void main(String[] args) throws IOException {
        //1、创建ServerSocket对象
        ServerSocket ss = new ServerSocket(8899);
        System.out.println("图片服务器已开启....");

        while(true){
            //2、获取Socket对象
            Socket socket = ss.accept();
            //开启线程执行上传图片操作
            new Thread(new UploadThread(socket)).start();

        }
    }
}
class UploadThread implements Runnable{
    Socket socket;
    public  UploadThread(Socket socket){
        this.socket = socket;
    }

    @Override
    public void run() {
        //通过socket对象获取输入流
        try {
            InputStream in = socket.getInputStream();
            //思路:文件上传,读取到图片之后将图片保存在服务器上的upload文件夹中
            String newFilename = UUID.randomUUID().toString().replace("-","");
            FileOutputStream fos = new FileOutputStream("upload\\"+newFilename+".jpg");

            byte[] buf = new byte[1024];
            int len ;
            while((len = in.read(buf))!=-1){
                fos.write(buf,0,len);
            }
            //获取输出流向客户端发送数据
            OutputStream out = socket.getOutputStream();
            out.write(("success!!!"+"upload\\"+newFilename+".jpg").getBytes());

            //4、关闭资源
            out.close();
            fos.close();
            in.close();
            socket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

16.6 基于UDP协议通信

16.6.1 案例1

发送端发送数据到接收端

public class Send {
    public static void main(String[] args) throws  Exception {
        //1、基于UDP协议创建Socket对象   无需指定端口号ip地址
        DatagramSocket ds = new DatagramSocket();
        //2、创建数据包对象
        byte[] buf = "你好接收端".getBytes();
        DatagramPacket dp = new DatagramPacket(buf,buf.length, InetAddress.getByName("192.168.73.210"),9999);
        //3、发送数据包
        ds.send(dp);
        //4、释放资源
        ds.close();
    }
}

public class Receive {
    public static void main(String[] args) throws Exception {
        //1、基于UDP协议创建Socket对象
        DatagramSocket ds = new DatagramSocket(9999);
        //2、创建数据包对象
        byte[] buf = new byte[1024];
        DatagramPacket dp = new DatagramPacket(buf,buf.length);
        //3、接受数据包  receive阻塞式的方法
        ds.receive(dp);

        //4、解析数据包的数据
        //从数据包中获取数据
        byte[] data = dp.getData();
        //从数据包中获取InetAddress对象
        InetAddress inetAddress = dp.getAddress();
        //从数据包中获取端口号
        int port = dp.getPort();
        //获取数据包的数据字节数长度
        int length = dp.getLength();


        String str = new String(data,0,length);
        System.out.println("ip:"+inetAddress.getHostAddress());
        System.out.println("port:"+port);
        System.out.println("data:"+str);

        //5、释放资源
        ds.close();
    }
}

16.6.2 案例2

使用UDP协议向飞秋发送数据

public class Send {
    public static void main(String[] args) throws Exception {
        //分析:只要搞清楚飞秋的数据包的格式
        //1:100:主机名:昵称:32:hello,飞秋
        //1、创建Socket对象
        DatagramSocket ds = new DatagramSocket();
        //2、创数据包对象
        byte[] buf = "1:100:主机名:昵称:32:hello,飞秋".getBytes("GBK");
        DatagramPacket dp = new DatagramPacket(buf,buf.length, InetAddress.getByName("192.168.73.210"),2425);
        //3、发送数据包
        ds.send(dp);
        //4、释放资源
        ds.close();
    }
}
目录
相关文章
|
2月前
|
Java
【思维导图】JAVA网络编程思维升级:URL与URLConnection的逻辑梳理,助你一臂之力!
【思维导图】JAVA网络编程思维升级:URL与URLConnection的逻辑梳理,助你一臂之力!
42 1
|
2月前
|
XML JSON 搜索推荐
【高手过招】JAVA网络编程对决:URL与URLConnection的高级玩法,你敢挑战吗?
【高手过招】JAVA网络编程对决:URL与URLConnection的高级玩法,你敢挑战吗?
55 0
|
19天前
|
安全 网络协议 Java
Java 网络编程详解
《Java网络编程详解》深入浅出地讲解了使用Java进行网络编程的技术和方法。从基础的网络协议介绍到核心的Socket编程,以及高级的NIO与多线程应用,帮助读者全面掌握Java网络编程技能,是Java开发者不可或缺的学习指南。
|
1月前
|
网络协议 Java
谈谈TCP/IP网络编程
【9月更文挑战第1天】在当今数字化的世界中,网络通信是连接各种设备和系统的关键。TCP/IP协议作为互联网通信的基石,被广泛应用于各种网络场景。了解TCP/IP网络编程的概念,并掌握如何在Java中实现TCP/IP通讯,对于开发人员来说是非常重要的。
60 4
|
2月前
|
网络协议 C# 开发者
WPF与Socket编程的完美邂逅:打造流畅网络通信体验——从客户端到服务器端,手把手教你实现基于Socket的实时数据交换
【8月更文挑战第31天】网络通信在现代应用中至关重要,Socket编程作为其实现基础,即便在主要用于桌面应用的Windows Presentation Foundation(WPF)中也发挥着重要作用。本文通过最佳实践,详细介绍如何在WPF应用中利用Socket实现网络通信,包括创建WPF项目、设计用户界面、实现Socket通信逻辑及搭建简单服务器端的全过程。具体步骤涵盖从UI设计到前后端交互的各个环节,并附有详尽示例代码,助力WPF开发者掌握这一关键技术,拓展应用程序的功能与实用性。
92 0
|
11天前
|
存储 安全 算法
网络安全与信息安全:构建安全数字生活的基石
【10月更文挑战第5天】 在数字化时代,网络安全与信息安全已成为维护个人隐私、企业机密和国家安全的重要防线。本文旨在探讨网络安全漏洞的形成与防范、加密技术的应用及其重要性,以及提升公众安全意识的必要性。通过深入浅出的方式,帮助读者理解网络安全的核心要素,并强调每个人都是网络安全生态中不可或缺的一环。
37 1
|
12天前
|
存储 安全 程序员
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【10月更文挑战第5天】 本文旨在探讨网络安全和信息安全领域的重要方面,包括网络漏洞、加密技术及安全意识。通过深入分析这些关键概念,我们希望提高读者对这些重要领域的理解,并强调在当今数字化世界中保护个人和组织数据的重要性。我们将从网络漏洞的定义及其成因开始,接着介绍常见的加密技术及其应用,最后讨论提升安全意识的方法,以帮助读者更好地保护自己的信息安全。
|
11天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
【10月更文挑战第6天】在数字化时代,网络安全和信息安全已成为我们生活中不可或缺的一部分。本文将探讨网络安全漏洞、加密技术和安全意识等方面的内容,以帮助读者更好地了解这些主题,并采取适当的措施保护自己的信息安全。我们将通过代码示例来演示一些常见的安全漏洞,并提供解决方案。最后,我们将强调培养良好的安全意识对于维护个人和组织的信息安全的重要性。
|
8天前
|
安全 网络安全 数据安全/隐私保护
网络安全与信息安全:守护数字世界的坚盾
在数字化浪潮中,网络安全已成为维系现代社会正常运转的关键。本文旨在探讨网络安全漏洞的成因、加密技术的应用及安全意识的提升,以期为广大用户和技术人员提供实用的知识分享。通过对这些方面的深入剖析,我们期望能够共同构建一个更加安全可靠的数字环境。
|
9天前
|
存储 SQL 安全
网络安全与信息安全的守护之盾
本文将深入探讨网络安全漏洞、加密技术及安全意识的重要性,旨在帮助读者建立全面的网络安全知识体系。