IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> Java进阶(五)网络编程 -> 正文阅读

[网络协议]Java进阶(五)网络编程

网络编程

  • 什么是网络?

    由点和线构成表示诸多对象间的互相联系。在生活当中,人际关系是一种网络,足球网是一种网络,蜘蛛网也是一种网络。

1.1计算机网络

  • 什么是计算机网络?

    为实现资源共享和信息传递,通过通信线路连接起来的若干主机(Host)。比如多个独立的主机/电脑通过双绞线或者光纤连接起来就形成了计算机网络。

  • 按照地理范围网络分为:

    • 局域网。

      范围比较小,可能是一间教室,一栋大楼或者一个校区。

    • 地域网。

      可以是一个或者多个城市形成的网络。

    • 广域网。

      最大的网络,又可以分为:

      • 互联网:(Internet)点与点相连。
      • 万维网:(WWW - World Wide Web)端与端相连。
      • 物联网:(IoT - Internet of things)物与物相连。
  • 网络编程:

    让计算机与计算机之间建立连接进行通信

2. 网络模型

2.1 OSI参考模型

  • OSI(Open System Interconnection)开放式系统互联。

img

这个模型把整个网络的建设分成了七层,下层为上层服务:

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

举个实际例子,假设我在QQ上给我的学妹发了条“我喜欢你”,这条信息会从应用层向下到物理层进行传递,每下一层都会包裹某种协议,最后在物理层转换为数字信号或者光信号等通过网卡或者路由器等传递到学妹端的物理层,这种信号又从物理层往上到应用层,学妹就能看见我发了条信息,学妹也能以这样的方式给我回复消息,有可能是“你是个好人”等其他信息,这是一个双向的传递。在这个过程中,涉及到各层的协议,协议实际就是约定数据传输的格式,我发送了中文,别人也一定看到的是同样的内容。

2.2 TCP/IP模型

  • 一组用于实现网络互连的通信协议,将协议分为四个层次。

img

由于OSI参考模型采用的是七层的建设模型,比较复杂,所以在网络建设中一般采用的是TCP/IP模型。实际上TCP/IP模型的四层也对应这OSI模型的七层,它将OSI的五到七层合成了应用层,把一二层合成了网络接口层。

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

3. 通信协议

3.1 TCP协议

  • TCP协议:Transmission Control Protocol 传输控制协议
  • 是一种面向连接的可靠的面向字节流的传输层通信协议。数据大小无限制。建立连接的过程需要三次握手,断开连接的过程需要四次挥手。
  • 面向连接的意思就是两台计算机(应用程序)在通信之前,必须先建立连接。
  • TCP的三次握手,或者说三报文握手,是TCP建立连接过程的机制。主动发起TCP连接的应用进程叫做客户,而被动等待连接建立的应用程序叫做服务器。客户向服务器发送请求后,服务器要确认客户的连接请求,然后客户要对服务器的确认进行确认。
  • TCP的四次挥手,或者说四报文握手,是TCP释放连接过程的机制。任何一方都可以在数据传送结束后发出连接释放的通知,待对方确认后就进入了半关闭状态。当另一方也没有数据再发送时,则发送连接释放通知,对方确认后就完全关闭了TCP连接。
  • “面向字节流”的含义是:虽然应用程序和TCP的交互试一次一个数据块(大小不等),但TCP把应用程序交下来的数据仅仅看成是一连串的无结构的字节流。TCP并不知道所传送的字节流的含义。TCP不保证接收方应用程序所收到的数据块和发送方应用程序所发出的数据块具有对应大小的关系(例如,发送方应用程序交给发送方的TCP共10个数据块,但接收方的TCP可能只用了4个数据块就把收到的字节流交付给上层的应用程序)。但接收方的应用程序收到的字节流必须和发送方应用程序发出的字节流完全一样。

3.2 UDP协议

  • UDP协议:User Datagram Protocol用户数据报协议
  • 是一种无连接的传输层协议,提供面向报文的简单不可靠信息传送服务,每个包的大小是64KB。
  • 无连接是指UDP在传送数据之前不需要先建立连接。远地主机的运输层在收到UDP报文后,不需要给出任何确认。虽然UDP不提供可靠交付,但在某些情况下UDP却是一种最有效的工作方式。
  • “面向报文”简单说就是应用层交给UDP多长的报文,UDP就照样发送,即一次发送一个报文。也就是说,UDP一次交付一个完整的报文。

3.3 IP协议

IP协议:Internet Protocol 互联网协议/网际协议

  • 负责数据从一台机器发送到另一台机器。
  • 给互联网每台设备分配一个唯一标识(IP地址)。

IP地址分为两种:

  • IPV4:4字节32位整数,并分成4段8位的二进制数,每8位之间用圆点隔开,每8位整数可以转换为一个0~255的十进制整数。

    格式:D.D.D.D 例如:255.255.255.255

    IPV4是上个世纪70年代出现的一个版本,到现在差不多五十年,所以面临着一个资源耗尽的问题。在上个世纪90年代出现了IP的第6个版本,据说IPV6可以给地球的每一个沙子分配一个IP。

  • IPV6:16字节128位整数,并分成8段十六进制数,每16位之间用圆点隔开,每16位整数可以转换为一个0~65535的十进制数。

    格式:X.X.X.X.X.X.X.X 例如:FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF.FFFF

    这里的4和6是IP的第4个和第6个版本,版本1~3和版本5都未曾使用过。

IPV4的应用分类:

  • 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命令:ping D.D.D.D

    比如你可以打开cmd,输入ping www.baidu.com

  • 查看IP命令:ipconfig

  • package Demo01;
    
    import java.net.InetAddress;
    import java.net.UnknownHostException;
    
    // 测试IP
    public class TestInetAddress {
        public static void main(String[] args) {
            try {
                // 查询本机地址
                InetAddress inetAddress1 = InetAddress.getByName("127.0.0.1");
                System.out.println(inetAddress1);
                InetAddress inetAddress3 = InetAddress.getByName("localhost");
                System.out.println(inetAddress3);
                InetAddress inetAddress4 = InetAddress.getLocalHost();
                System.out.println(inetAddress4);
    
                // 查询网络地址
                InetAddress inetAddress2 = InetAddress.getByName("www.baidu.com");
                System.out.println(inetAddress2);
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }
    

3.4 Port端口

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

    举个例子,我用IP地址为192.168.0.1的电脑上的QQ程序,给学妹的IP地址为192.168.0.2的电脑上的QQ发送一条信息“我喜欢你”,而且我还用电脑上的微信发送了相同的信息给学妹电脑上的微信,那么这两条信息发送的IP地址都是学妹的电脑192.168.0.2,如何保证QQ的消息不会发送到微信上,不至于出现混乱?所以,程序在发送信息的时候,不仅要知道对方的IP地址,还要知道程序的端口号。

  • 端口分类(一般是两个字节):

    • 公认端口:0~1023

      像这样的端口号是被占用的,我们不能使用。

    • 注册端口:1024~49151

    • 动态或私有端口:49152~65535

      像这样的端口号是动态分配的,而且两个网络程序不可能出现端口号相同的情况,但是对于TCP/UDP协议,他们是两套端口号,它们端口号相同是不冲突的,每个协议都是独立的。

  • 常用端口:

    • MySql:3306
    • Oracle:1521
    • Tomcat:8080
    • SMTP:25
    • Web服务器:80
    • FTP服务器:21
package Demo01;

import java.net.InetSocketAddress;

public class TestInetSocketAddress {
    public static void main(String[] args) {
        InetSocketAddress socketAddress1 = new InetSocketAddress("127.0.0.1", 8080);
        InetSocketAddress socketAddress2 = new InetSocketAddress("localhost", 8080);
        System.out.println(socketAddress1);
        System.out.println(socketAddress2);

        System.out.println(socketAddress1.getAddress());
        System.out.println(socketAddress1.getHostName());
        System.out.println(socketAddress1.getPort());
    }
}

4.TCP

4.1 服务端

  • 创建地址
  • 等待连接
  • 读取消息
  • 关闭连接
//服务端
public class TCPServerDemo01 {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;

        try {
            //1.我有一个地址
            serverSocket = new ServerSocket(9999);
            //2.等待客户端连接
            socket = serverSocket.accept();
            //3.读取客户端的消息
            is = socket.getInputStream();

            //管道流
            baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024];
            int len;
            while ((len = is.read(buffer))!=-1){
                baos.write(buffer,0,len);
            }

            System.out.println(baos.toString());

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            baos.close();
            is.close();
            socket.close();
            serverSocket.close();
        }
    }
}

4.2 客户端

  • 获取服务器地址
  • 创建socket连接
  • 发送消息
  • 关闭连接
//客户端
public class TcpClientDemo01 {
    public static void main(String[] args) throws IOException {

        Socket socket = null;
        OutputStream os = null;

        try {
            //1.我知道一个服务器的地址
            InetAddress serverIP = InetAddress.getByName("127.0.0.1");
            int port = 9999;
            //2.创建一个socket连接
            socket = new Socket(serverIP,port);
            //3.发送消息
            os = socket.getOutputStream();
            os.write("您好呀".getBytes());


        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            os.close();
            socket.close();
        }
    }
}

4.3 文件上传

  • 服务器端
public class TcpServerDemo02 {
    public static void main(String[] args) throws IOException {
        //1.创建服务
        ServerSocket serverSocket = new ServerSocket(9000);
        System.out.println("服务器开始启动---");
        //2.监听客户端连接
        Socket socket = serverSocket.accept();//阻塞式监听
        //3.获取输入流
        InputStream is = socket.getInputStream();
        //4.管道输出流文件输出
        FileOutputStream fos = new FileOutputStream(new File("receive.jpg"));
        byte[] buffer = new byte[1024];
        int len;
        while ((len = is.read(buffer))!=-1){
            fos.write(buffer,0,len);
        }
        //5.通知客户端我接收完毕了
        OutputStream os = socket.getOutputStream();
        os.write("我接收完毕了,你可以断开了".getBytes(StandardCharsets.UTF_8));

        //6.关闭资源
        fos.close();
        is.close();
        socket.close();
        serverSocket.close();
    }
}
  • 客户端
//文件上传
public class TcpClientDemo02 {
    public static void main(String[] args) throws IOException {
        //1.创建一个socket连接
        Socket socket = new Socket(InetAddress.getByName("127.0.0.1"),9000);
        //2.创建一个输出流
        OutputStream os = socket.getOutputStream();
        //3.读取文件
        FileInputStream fis = new FileInputStream(new File("f:\\source\\2.jpg"));
        //4.写出文件
        byte[] buffer = new byte[1024];
        int len;
        while ((len = fis.read(buffer))!=-1){
            os.write(buffer,0,len);
        }

        //通知服务器 我已经传输完了
        socket.shutdownOutput();

        //5.确认服务器接收完毕,才能断开
        InputStream inputStreamReader = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[1024];
        int len2;
        while ((len2 = inputStreamReader.read(buffer2))!=-1){
            baos.write(buffer,0,len2);
        }
        System.out.println(baos.toString());
        //6.关闭资源
        baos.close();
        inputStreamReader.close();
        fis.close();
        os.close();
        socket.close();
    }
}

5.初识Tomcat

服务端

  • 自定义 S
  • Tomcat服务器 S : JAVA后台开发

客户端

  • 自定义 C
  • 浏览器 B

6.UDP

  • UDP不需要知道建立连接
  • 需要知道对方的地址

6.1 服务端

public class UdpServerDemo01 {
    public static void main(String[] args) throws Exception {
        // 开放端口
        DatagramSocket socket = new DatagramSocket(9090);
        // 接收数据包
        byte[] buffer = new byte[1024];
        DatagramPacket packet = new DatagramPacket(buffer, 0, buffer.length);
        socket.receive(packet); // 阻塞接收
        System.out.println(packet.getAddress().getHostAddress());
        System.out.println(new String(packet.getData(), 0, packet.getLength()));

        // 关闭资源
        socket.close();
    }
}

6.2 客户端

public class UdpClientDemo01 {
    public static void main(String[] args) throws Exception {
        //1. 建立一个socket
        DatagramSocket socket = new DatagramSocket();
        // 2. 建包
        String msg = "hello world";
        InetAddress localhost = InetAddress.getByName("localhost");
        int port = 9090;

        // 数据, 数据长度起始, 发送目的
        DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);

        // 3. 发送包
        socket.send(packet);
        // 关闭资源
        socket.close();
    }
}

6.3 聊天案例

  • 服务端
public class UdpReceiver {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(6666);

        while(true){
            // prepare receive the packet
            byte[] container = new byte[1024];
            DatagramPacket packet = new DatagramPacket(container, 0, container.length);
            socket.receive(packet); // 阻塞式接收

            // 断开连接 bye
            byte[] data = packet.getData();
            String receiveData = new String(data, 0, data.length);
            System.out.println(receiveData);
            if (receiveData.equals("bye")) break;
        }
        socket.close();
    }
}
  • 客户端
public class UdpSender {
    public static void main(String[] args) throws Exception {
        DatagramSocket socket = new DatagramSocket(8888);
        // 准备数据 从控制台读取 system.in
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));

        while (true){
            String data = reader.readLine();
            byte[] datas = data.getBytes();
            DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress("localhost", 6666));

            socket.send(packet);
            if(data.equals("bye")) {
                break;
            }
        }
        socket.close();
    }
}

6.4 多线程互发消息案例

  • 接收端
public class TalkReceive implements Runnable {
    DatagramSocket socket = null;
    private int port;
    private String msgFrom;
    public TalkReceive(int port, String msgFrom){
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void run() {
        try {
            while(true){
                // prepare receive the packet
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container, 0, container.length);
                socket.receive(packet); // 阻塞式接收

                // 断开连接 bye
                byte[] data = packet.getData();
                String receiveData = new String(data, 0, data.length);
                System.out.println(msgFrom + ":" + receiveData);
                if (receiveData.equals("bye")) break;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        socket.close();
    }
}
  • 发送端
package com.company.chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;
import java.util.concurrent.ExecutionException;

public class TalkSend implements Runnable {
    DatagramSocket socket = null;
    BufferedReader reader = null;
    private int fromPort;
    private String toIP;
    private int toPort;

    public TalkSend(int fromPort, String toIP, int toPort) {
        this.fromPort = fromPort;
        this.toIP = toIP;
        this.toPort = toPort;
        try{
            socket = new DatagramSocket(fromPort);
            reader = new BufferedReader(new InputStreamReader(System.in));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        while (true){
            String data = null;
            try {
                data = reader.readLine();
                byte[] datas = data.getBytes();
                DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, new InetSocketAddress(this.toIP, this.toPort));

                socket.send(packet);
                if(data.equals("bye")) {
                    break;
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        socket.close();
    }
}
  • 两个不同实例
public class TalkTeacher {
    public static void main(String[] args) {
        new Thread(new TalkSend(5555, "localhost", 8888)).start();
        new Thread(new TalkReceive(9999, "Stu")).start();
    }
}
public class TalkStudent {

    public static void main(String[] args) {
           // 开启两个线程
            new Thread(new TalkSend(7878, "localhost", 9999)).start();
            new Thread(new TalkReceive(8888, "teac")).start(); }
}

7.URL

  • 统一资源定位符:定位资源,定位互联网上的某一个资源

DNS域名解析

协议:// ip 地址:端口/ 项目名 / 资源
  • 下载网络资源
public class UrlDown {
    public static void main(String[] args) throws Exception {
        // 1. download Address
        URL url = new URL("http://twblog.ga/pic/dog.jpg"); // 网络资源地址
        // 2. connect HTTP
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        InputStream inputStream = urlConnection.getInputStream();

        FileOutputStream fos = new FileOutputStream("ok.jpg"); // 下来的命名

        byte[] buffer = new byte[1024];
        int len;
        while((len = inputStream.read(buffer)) != -1){
            fos.write(buffer, 0, len); // 写出数据
        }
        fos.close();
        inputStream.close();
        urlConnection.disconnect(); // 断开连接
    }
}
 // 1. download Address
    URL url = new URL("http://twblog.ga/pic/dog.jpg"); // 网络资源地址
    // 2. connect HTTP
    HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
    InputStream inputStream = urlConnection.getInputStream();

    FileOutputStream fos = new FileOutputStream("ok.jpg"); // 下来的命名

    byte[] buffer = new byte[1024];
    int len;
    while((len = inputStream.read(buffer)) != -1){
        fos.write(buffer, 0, len); // 写出数据
    }
    fos.close();
    inputStream.close();
    urlConnection.disconnect(); // 断开连接
}

}


  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-07-30 13:06:15  更:2021-07-30 13:08:24 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 18:30:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码