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 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 网络编程基础 -> 正文阅读

[网络协议]网络编程基础

一、基础
  • 计算机网络:计算机网络是指将地理位置不同的具有独立功能的多台计算机及其外部设备,通过通信线路连接起来,在网络操作系统,网络管理软件及网络通信协议的管理和协调下,实现资源共享和信息传递的计算机系统。

  • 网络通信的要素:

    1. 通信双方的地址:IP和端口号

    2. 网络通信协议:OSI参考模型 和 TCP/IP参考模型(协议)

      在这里插入图片描述

二、IP

获取IP地址:InetAddress类

  • 唯一定位一台网络上的计算机

  • 127.0.0.1:指代本机(localhost)

  • IP地址的分类:

    • IPV4/IPV6:

      IPV4:例如127.0.0.1:由4个字节组成,每个字节0~255,总计约42亿个,2011年就用尽了

      IPV6:例如fe80::d8e8:3f1a:5ab0:8904%7:128位,8个无符号整数

    • 公网(互联网)/私网(局域网)

      ABCD类IP地址

      192.168.XXX.XXX:专门给组织内部使用的

package com.bravo.demo.network;

import java.net.InetAddress;
import java.net.UnknownHostException;

public class TestInetAddress {
    public static void main(String[] args) {
        try {
            //查询本机地址
            InetAddress address1 = InetAddress.getByName("127.0.0.1");
            InetAddress address2 = InetAddress.getByName("localhost");
            InetAddress address3 = InetAddress.getLocalHost();
            System.out.println("address1:"+address1);
            System.out.println("address2:"+address2);
            System.out.println("address3:"+address3);

            //查询网站地址
            InetAddress address4 = InetAddress.getByName("www.baidu.com");
            System.out.println("address4:"+address4);

            //常用方法
            System.out.println("---------------------------");
            System.out.println(address4.getAddress());
            System.out.println(address4.getCanonicalHostName());//获取规范的名字
            System.out.println(address4.getHostAddress());//获取IP
            System.out.println(address4.getHostName());//获取域名或者本机名称
        } catch (UnknownHostException e) {
            e.printStackTrace();
        }
    }
}

控制台输出结果:

address1:/127.0.0.1
address2:localhost/127.0.0.1
address3:LAPTOP-NIVLBH1R/192.168.0.7
address4:www.baidu.com/110.242.68.3
---------------------------
[B@7530d0a
110.242.68.3
110.242.68.3
www.baidu.com
三、端口

端口是指计算机上一个程序的进程:

  • 不同的进程有不同的端口号,用来区分软件

  • 端口号只有整数,范围为0~65535

  • 按对应的协议类型,端口有TCP端口和UDP端口两种。由于TCP协议和UDP协议是相互独立的,因此各自的端口号也相互独立,比如TCP有80端口,UDP也可以有80端口,两者并不冲突。

  • 端口分类:

    • 公有端口:0~1023

      比如:HTTP默认端口:80

      ? HTTPS默认端口:443

      ? FTP默认端口:21

      ? SSH默认端口:22

      ? 等等。

    • 程序注册端口:1024~49151,分配给用户或者程序

      比如:MYSQL默认端口:3306

      ? Redis默认端口:6379

      ? Tomcat默认端口:8080

      ? Nginx默认端口:8888

      ? Oracle默认端口:1521

      ? 等等。

    • 动态(私有)端口:49152~65535

  • 常见的DOS命令:

    1. 查看所有端口命令:netstat -ano
    2. 查看指定的端口:netstat -ano|findstr “XXX” (XXX代表端口号)
    3. 查看指定端口的进程:tasklist|findstr “XXX” (XXX代表端口号)
package com.bravo.demo.network;

import java.net.InetSocketAddress;

public class TestInetSocketAddress {

    public static void main(String[] args) {
        InetSocketAddress address1 = new InetSocketAddress("127.0.0.1", 8080);
        InetSocketAddress address2 = new InetSocketAddress("localhost", 8080);
        System.out.println("address1:"+address1);
        System.out.println("address2:"+address2);

        System.out.println(address2.getHostName());
        System.out.println(address2.getHostString());
        System.out.println(address2.getPort());
    }
}

控制台输出结果:

address1:/127.0.0.1:8080
address2:localhost/127.0.0.1:8080
localhost
localhost
8080
四、通信协议

TCP/IP协议是网络相关各类协议簇的总称,包括TCP,UDP,IP,FTP,HTTP,ICMP,SMTP等

TCP:用户传输协议

UDP:用户数据报协议

IP:网络互联协议

  • TCP和UDP对比:
区别点TCPUDP
是否连接面向连接无连接
是否可靠可靠传输,使用流量控制和拥塞控制不可靠传输,不使用流量控制和拥塞控制
连接对象个数只能是一对一通信支持一对一,一对多,多对一和多对多交互通信
传输方式面向字节流面向报文
首部开销首部最小20字节,最大60字节首部开销小,仅8字节
适用场景适用于要求可靠传输的应用,例如文件传输适用于实时应用(IP电话、视频会议、直播等)

TCP可理解为打电话(需要双方连接),UDP可理解为发短信(只需要一方发送,对方是否接受成功不知道)

  • TCP三次握手(比喻):

    客户端:我准备建立连接了
    服务端:知道了
    客户端:好的
    
  • TCP四次挥手(比喻):

    客户端:我准备断开连接了
    服务端:知道了,还没处理完先等一下
    服务端:我处理好了,可以断开连接
    服务端:好的
    
五、TCP实现会话

客户端:1. 连接服务端Socket;2. 发送消息

package com.bravo.demo.network;

import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;

/**
 * 客户端
 */
public class TcpClientDemo1 {

    public static void main(String[] args) {
        Socket socket = null;
        OutputStream os = null;
        try {
            //需要知道服务端地址(IP)
            InetAddress serverIP = InetAddress.getByName("127.0.0.1");
            //端口号
            int port=9999;
            //创建一个socket连接
            socket = new Socket(serverIP,port);
            //发送消息,IO流
            os = socket.getOutputStream();
            os.write("Hello,world!".getBytes());

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭流
            if(os!=null){
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket!=null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

服务端:1. 建立服务端口ServerSocket;2. 等待客户端连接accept;3. 接受客户端消息

package com.bravo.demo.network;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 */
public class TcpServerDemo1 {

    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket socket = null;
        InputStream is = null;
        ByteArrayOutputStream baos = null;
        try {
            //需要有一个自己的地址(IP)
            serverSocket = new ServerSocket(9999);
            //等待客户端连接
            socket = serverSocket.accept();
            //读取客户端消息
            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 {
            //关闭流
            if(baos!=null){
                try {
                    baos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(is!=null){
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(socket!=null){
                try {
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(serverSocket!=null){
                try {
                    serverSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

先启动服务端,再启动客户端,服务端就会收到一条“Hello,world!”的消息

六、TCP实现文件传输
  • 客户端:
package com.bravo.demo.network;

import java.io.*;
import java.net.InetAddress;
import java.net.Socket;

/**
 * 客户端
 */
public class TcpClientDemo2 {

    public static void main(String[] args) throws Exception {
        //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("1.jpg"));//1.jpg为在项目根目录下的图片文件
        //4.写出文件
        byte[] buffer = new byte[1024];
        int len;
        while((len=fis.read(buffer))!=-1){
            os.write(buffer,0,len);
        }

        //通知服务端,已经传输完毕
        socket.shutdownOutput();

        //确定服务端接受完毕才能断开连接
        InputStream is = socket.getInputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer2 = new byte[2014];
        int len2;
        while((len2=is.read(buffer2))!=-1){
            baos.write(buffer2,0,len2);
        }
        System.out.println(baos.toString());

        //5.关闭资源
        fis.close();
        os.close();
        socket.close();
    }
}
  • 服务端
package com.bravo.demo.network;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 服务端
 */
public class TcpServerDemo2 {

    public static void main(String[] args) throws Exception {
        //1.创建服务端口
        ServerSocket serverSocket = new ServerSocket(9000);
        //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);
        }

        //通知客户端接受完毕
        OutputStream os = socket.getOutputStream();
        os.write("服务端接受完毕了,客户端可以断开连接了".getBytes());


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

先启动服务端,再启动客户端,客户端会输出“服务端接受完毕了,客户端可以断开连接了”,项目根目录出现一张名为receive.jpg的图片

七、UDP发送消息
  • 发送端:

    package com.bravo.demo.network;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    /**
     * UDP发送端
     */
    public class UdpClientDemo1 {
    
        public static void main(String[] args) throws Exception{
            //1.建立一个Socket
            DatagramSocket socket = new DatagramSocket();
    
            //2.建立包
            String msg="你好!";
            InetAddress localhost = InetAddress.getByName("localhost");
            int port=9090;
            //DatagramPacket构造参数分别代表发送的数据、数据起始、终止、接受IP、接受端口
            DatagramPacket packet = new DatagramPacket(msg.getBytes(), 0, msg.getBytes().length, localhost, port);
    
            //3.发送包
            socket.send(packet);
    
            //4.关闭资源
            socket.close();
            
        }
    }
    
  • 接收端:

    package com.bravo.demo.network;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    /**
     * UDP接收端
     */
    public class UdpServerDemo1 {
    
        public static void main(String[] args) throws Exception{
            //1.开放端口
            DatagramSocket socket = new DatagramSocket(9090);
            //2.接受数据包
            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()));
            //3.关闭连接
            socket.close();
        }
    
    }
    

    UDP不需要在发送端和接收端直接建立连接

八、UDP循环发送消息
  • 发送端

    package com.bravo.demo.network;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    
    /**
    * 发送端
    */
    public class UdpSendDemo1 {
    
        public static void main(String[] args) throws Exception{
    
            DatagramSocket socket = new DatagramSocket(8888);
            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, InetAddress.getByName("127.0.0.1"), 6666);
                socket.send(packet);
                
                //发送“bye”时终止程序
                if("bye".equals(data)){
                    break;
                }
            }
            socket.close();
    
        }
    }
    
  • 接收端

    package com.bravo.demo.network;
    
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    
    /**
     * 接收端
     */
    public class UdpReceiveDemo1 {
    
        public static void main(String[] args) throws Exception{
            DatagramSocket socket = new DatagramSocket(6666);
            while(true){
                byte[] buffer = new byte[1024];
                DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
                socket.receive(packet);//阻塞式接收包裹
    
                byte[] data = packet.getData();
                String receiveData=new String(data,0,data.length);
                System.out.println("收到发送端消息:"+receiveData);
                
                //接收“bye”时终止程序
                if("bye".equals(receiveData.trim())){
                    break;
                }
            }
            socket.close();
        }
    }
    
九、UDP多线程相互发送消息
  • 发送端线程

    package com.bravo.demo.network;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    
    /**
     * 发送端
     */
    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 (SocketException e) {
                e.printStackTrace();
            }
        }
    
        @Override
        public void run() {
            while (true){
                try {
                    String data = reader.readLine();
                    byte[] datas = data.getBytes();
                    DatagramPacket packet = new DatagramPacket(datas, 0, datas.length, InetAddress.getByName(this.toIP), this.toPort);
                    socket.send(packet);
                    if("bye".equals(data)){
                        break;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            socket.close();
        }
    }
    
  • 接收端线程

    package com.bravo.demo.network;
    
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketException;
    
    /**
     * 接收端
     */
    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() {
            while(true){
                try {
                    byte[] buffer = new byte[1024];
                    DatagramPacket packet = new DatagramPacket(buffer,0,buffer.length);
                    socket.receive(packet);//阻塞式接收包裹
    
                    byte[] data = packet.getData();
                    String receiveData=new String(data,0,data.length);
                    System.out.println(msgFrom+":"+receiveData);
                    if("bye".equals(receiveData.trim())){
                        break;
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            socket.close();
        }
    }
    
  • 开启两个线程

    package com.bravo.demo.network;
    
    public class TalkStudent {
    
        public static void main(String[] args) {
            //开启两个线程
            new Thread(new TalkSend(7777,"localhost",9999)).start();
            new Thread(new TalkReceive(8888,"老师")).start();
        }
    }
    
    package com.bravo.demo.network;
    
    public class TalkTeacher {
    
        public static void main(String[] args) {
            new Thread(new TalkSend(5555,"localhost",8888)).start();
            new Thread(new TalkReceive(9999,"学生")).start();
        }
    }
    
十、URL

URL(统一资源定位符):定位互联网上的某一个资源

URL常见格式:协议名://IP地址:端口号/项目名/资源

DNS域名解析:将域名解析为IP地址

  • URL类:
package com.bravo.demo.network;

import java.net.MalformedURLException;
import java.net.URL;

public class URLDemo1 {

    public static void main(String[] args) throws MalformedURLException {
        URL url = new URL("http://localhost:8080/helloworld/index.jsp?username=admin&password=111111");
        System.out.println(url.getProtocol());//获取此 URL的协议名称
        System.out.println(url.getHost());//获取此 URL的主机名
        System.out.println(url.getPort());//获取此 URL的端口号
        System.out.println(url.getPath());//获取此 URL的路径部分
        System.out.println(url.getFile());//获取此 URL的文件名
        System.out.println(url.getQuery());//获取此 URL的查询部分
    }
}

输出结果:

http
localhost
8080
/helloworld/index.jsp
/helloworld/index.jsp?username=admin&password=111111
username=admin&password=111111
  • URL建立连接,获取资源:
package com.bravo.demo.network;

import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class URLDemo2 {

    public static void main(String[] args) throws Exception {
        URL url = new URL("http://music.163.com/song/media/outer/url?id=853708.mp3");
        URLConnection connection = url.openConnection();
        InputStream is = connection.getInputStream();
        FileOutputStream fos =new FileOutputStream("download.mp3");

        byte[] buffer = new byte[1024];
        int len;
        while((len=is.read(buffer))!=-1){
            fos.write(buffer,0,buffer.length);
        }
        System.out.println("下载资源成功!");
    }
}
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-19 12:24:57  更:2021-08-19 12:26:51 
 
开发: 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 20:53:43-

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