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

[网络协议]网络编程

网络相关概念

IP地址

  • 概念:用于唯一标识网络中的每台计算机
  • 查看IP地址,控制台 ipconfig
  • IP地址表示形式:点分十进制 xx.xx.xx.xx
  • 每个十进制数范围:0~255
  • IP地址组成 = 网络地址 + 主机地址,比如 192.168.16.69
  • IPv6是代替IPv4的下一代IP地址
  • IPv4最大的问题是地址资源有限,所有就有了IPv6
  • IPv4是4个字节32位 IPv6是16个字节128位
  • IPv4地址分类image-20210802085603012

域名和端口号

域名

  • www.baidu.com
  • 好处:为了方便记忆,解决IP难记问题
  • 概念:将IP地址映射成域名(HTTP协议)

端口号

  • 概念:用于标识主机中某个特定的网络程序(例如百度主机中它有很多服务网站服务,邮件服务,Tomcat服务等各种服务),通过端口来监听每一个服务,防止访问发生错乱。
  • 表示形式:以整数形式,范围0~65535
  • 0~1024已被占用(自己最好不要用),比如 ssh 22 ,ftp 21 ,smtp 25 ,http 80
  • 常见的网络程序端口号:tomcat:8080 mysql:3306 oracle:1521 sqlserver:1433

网络通讯协议

TCP/IP (Transmission Control Protocol/Internet Protocol)的简写,中文译名为传输控制协议/因特网互联协议,又叫网络通讯协议,这个协议是lnternet最基本的协议、Internet国际互联网络的基础,简单地说,就是由网络层的IP协议和传输层的TCP协议组成的

TCP协议:传输控制协议

  • 使用TCP协议前,须先建立TCP连接,形成传输数据通道
  • 传输前,采用"三次握手"方式,是可靠的
  • TCP协议进行通信的两个应用进程:客户端、服务端
  • 在连接中可进行大数据量的传输
  • 传输完毕,需释放已建立的连接,效率低UDP协议:用户数据协议

UDP协议:用户数据协议

  • 将数据、源、目的封装成数据包,不需要建立连接
  • 每个数据报的大小限制在64K内,不适合传输大量数据
  • 因无需连接,故是不可靠的
  • 发送数据结束时无需释放资源(因为不是面向连接的),速度快
  • 举例:厕所通知:发短信(给对方发消息,不用确定是否对方是否收到)

image-20210802095628882

image-20210802100030605

InetAddress

InetAddress是用于管理IP的类,没有构造器

1. 单例模式

2. 根据静态的方法来返回该对象

public class InetAddress_ {
    public static void main(String[] args) throws UnknownHostException {
        //获取本机的 InetAddress 对象
        InetAddress localHost = InetAddress.getLocalHost();
        System.out.println(localHost);//设备名称/IP地址  ->WIN-MBL1NG3RUMG/192.168.176.1

        //根据主机名,获取设备的 InetAddress 对象
        InetAddress byName = InetAddress.getByName("WIN-MBL1NG3RUMG");
        System.out.println(byName);

        //根据域名返回 InetAddress 对象
        InetAddress byName1 = InetAddress.getByName("www.baidu.com");
        System.out.println(byName1);//www.baidu.com/14.215.177.39

        //通过 InetAddress 对象 获取IP/域名
        String address = byName1.getHostAddress();
        String name = byName1.getHostName();
        System.out.println(name);//www.baidu.com
        System.out.println(address);//14.215.177.39
    }
}

Socket

基本介绍

  • 套接字(Socket)开发网络应用程序被广泛采用,以至于成为事实上的标准。
  • 通信的两端都要有Socket,是两台机器间通信的端点。
  • 网络通信其实就是Socket间的通信。
  • Socket允许程序把网络连接当成一个流,数据在两个Socket间通过IO传输。
  • 一般主动发起通信的应用程序属客户端,等待通信请求的为服务端。

TCP网络通讯编程

image-20210802143802632

字节流传输

可靠性

1

服务端 自己去使用了本地的某个端口 如下代码:端口9999

public class SocketTCPServer {
    public static void main(String[] args) throws IOException {
        //1.在本机的9999端口建立监听,等待连接
        //  要求本机没有其他服务在监听9999端口
        //  ServerSocket 可以通过accept() 返回多个socket[多个客服端连接服务器的并发]
        ServerSocket serverSocket = new ServerSocket(9999);
        System.out.println("服务端在9999端口监听等待连接...");
        //2.如果没有客服端去连接9999端口时,程序会 阻塞,等待连接,如果有客服端连接,则会返回Socket对象,程序继续执行
        Socket socket = serverSocket.accept();
        System.out.println("服务端 Socket = " + socket.getClass());

        //3.通过socket.getInputStream() 读取客服端在数据通道上的数据,显示
        InputStream is = socket.getInputStream();    //如果读不到内容,也会阻塞
        byte[] buff = new byte[1024];
        int readLen = 0;
        while ((readLen = is.read(buff)) != -1) {
            System.out.println(new String(buff,0,readLen));
        }
        //4.反馈给客服端
        OutputStream os = socket.getOutputStream();
        os.write("hello client".getBytes());
        socket.shutdownOutput();      //传输结束标记

        //5.关闭流和socket
        os.close();
        is.close();
        socket.close();
        serverSocket.close();
        System.out.println("服务端退出");
    }
}

客户端 在去连接服务端的端口时,TCP/IP协议也会随机给客服端一个端口,当在传送比较大的文件时(传输时间长)在Java的Terminal控制台输入netstat -an | more 就可以看到一个和本地端口8888号对应的一个端口号。

public class SocketTCPClient {
    public static void main(String[] args) throws IOException {
        //1.连接服务端  连接InetAddress.getLocalHost()本机服务端这个9999端口
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);
        System.out.println("客服端返回 Socket = "+socket.getClass());

        //2.连接之后,生成Socket,通过socket.getOutputStream()得到和socket相关联的输出流对象
        OutputStream os = socket.getOutputStream();

        //3.通过输出流,写入数据到数据通道
        os.write("hello server".getBytes());
        socket.shutdownOutput();      //传输结束标记

        //4.接受服务端反馈过来的信息
        InputStream is = socket.getInputStream();
        byte[] buff = new byte[1024];
        int readLen = 0;
        while ((readLen = is.read(buff)) != -1) {
            System.out.println(new String(buff,0,readLen));
        }
        //关闭流对象和socket,必须关闭
        is.close();
        os.close();
        socket.close();
        System.out.println("客服端退出");
    }
}

字符流传输

因为socket没有直接提供字符流的传输,如果想用字符流传输,可以通过转换流,将字节流转换成字符流再进行传输

服务端

public class SocketTCPServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(9999);
        Socket socket = serverSocket.accept();

        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        //System.out.println(br.readLine());	//只能读单行字符串
        
        String s = null;
        while (!(s = br.readLine()).equals("bye")) {
            System.out.println(s);
        }
        
        OutputStream os = socket.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
        bw.write("hello client 字符流\nhello client 字符流\nbye");
        bw.newLine();//用字符流就可以不用socket.shutdownOutput()标记但是前提是接收时一定要用readLine()接收
        bw.flush();//字符流,一定要手动刷新,不然不会写入到数据通道

        //5.关闭流和socket
        bw.close();
        br.close();
        socket.close();
        serverSocket.close();
        System.out.println("服务端退出");
    }
}

客户端

public class SocketTCPClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket(InetAddress.getLocalHost(), 9999);

        OutputStream os = socket.getOutputStream();
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
        bw.write("hello server 字符流\nhello server 字符流\nbye");
        bw.newLine();//用字符流就可以不用socket.shutdownOutput()标记但是前提是接收时一定要用readLine()接收
        bw.flush();//字符流,一定要手动刷新,不然不会写入到数据通道

        InputStream is = socket.getInputStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(is));
        //System.out.println(br.readLine());
        String s = null;
        while (!(s = br.readLine()).equals("bye")) {
            System.out.println(s);
        }
        
        //关闭流对象和socket,必须关闭
        br.close();
        bw.close();
        socket.close();
        System.out.println("客服端退出");
    }
}

问题?

System.out.println(br.readLine());	//这个可以读取一行数据

while ((s = br.readLine())!=null) {	//但是想要读取多行数据,这个做法为啥不行
    System.out.println(s);
}

原因
首先要明白什么叫流结束,对于读取文件流,读到文件末尾算结束,
但对于socket流,把某次写入到该流的字符读取完能认为该socket流结束吗?
不能,因为这个流还存在,即使流中已经没有数据,但仍然可以继续写出和读入,那么程序自然会继续读流,而流真正的结束就是关闭。
自我理解 待求证
应该是字符串读到最后一行应该不为null或者是不能读取到最后。 好像是关于IO的阻塞和非阻塞
解决办法 在文本的最后加一个字符串作为结束标记

while (!(s = br.readLine()).equals("bye")) {
    System.out.println(s);
}

netstat指令

  • netstat -an 可以查看当前主机网络情况,包括端口监听情况和网络连接情况
  • netstat -an|more 使查看的内容分页 按空格键 显示下一页
  • 要求在dos控制台下执行 ctrl+c 停止当前代码运行
  • Listening 表示某个端口在监听
  • 如果外部程序连接到该端口,就会显示一条连接信息

在这里插入图片描述

  • 本地地址(IP:端口号) 表示本地这个IP对应的端口号

  • 外部地址(IP:端口号) 表示外部连接到本地地址的IP和对应的端口号

  • 状态 表示监听的状态

  • 用管理员启动的dos控制台输入netstat -anb|more 还可以查看是什么在监听这个端口

    在这里插入图片描述

UDP网络通讯编程(了解)

基本介绍

  • 类 DatagramSocket和 DatagramPacket[数据包|数据报]实现了基于UDP协议网络程序。
  • UDP数据报通过数据报套接字DatagramSocket发送和接收,系统不保证UDP数据报一定能够安全送到目的地,也不能确定什么时候可以抵达。
  • DatagramPacket 对象封装了UDP数据报,在数据报中包含了发送端的IP地址和端口号以及接收端的IP地址和端口号。
  • UDP协议中每个数据报都给出了完整的地址信息,因此无须建立发送方和接收方的连接。

基本流程

在这里插入图片描述

案例
发送端 也可以说是接收端

public class UDPSenderB {
    public static void main(String[] args) throws IOException {
        //1.创建一个DatagramSocket对象,准备发送和接收数据
        DatagramSocket dgs = new DatagramSocket(9998);

        //2.将要发送的数据,封装到DatagramPacket对象
        byte[] bytes = "hello world".getBytes();//InetAddress.getLocalHost()不推荐用这个因为,此时能用是是因为发送和接收在一台机子上面
        DatagramPacket dgp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("192.168.159.1"), 9999);
        dgs.send(dgp);

        //3.接收数据
        byte[] buff = new byte[1024];
        dgp = new DatagramPacket(buff, buff.length);
        dgs.receive(dgp);
        int length = dgp.getLength();       //接收到数据的字节长度
        bytes = dgp.getData();
        String s = new String(bytes, 0, length);
        System.out.println(s);

        //3.关闭资源
        dgs.close();
        System.out.println("B退出");
    }
}

接收端 也可以说是发送端

public class UDPReceiverA {
    public static void main(String[] args) throws IOException {
        //1.创建一个DatagramSocket对象,准备在9999端口接收数据
        DatagramSocket dgs = new DatagramSocket(9999);

        //2.构建一个DatagramPacket对象,准备接收数据    UDP数据包大小为64K
        byte[] bytes = new byte[1024];   //64*1024
        DatagramPacket dgp = new DatagramPacket(bytes, bytes.length);

        //3.调用 接收方法  通过网络传输的DatagramPacket来填充DatagramSocket对象
        //  当有数据包发送到本机9999端口,就会接收到数据,没有发送,就会阻塞等待
        dgs.receive(dgp);

        //4.把dgs进行拆包,取出数据,并显示
        int length = dgp.getLength();       //接收到数据的字节长度
        bytes = dgp.getData();
        String s = new String(bytes, 0, length);
        System.out.println(s);

        //5.发送信息回去
        bytes = "你好 世界".getBytes();//InetAddress.getLocalHost()不推荐用这个因为,此时能用是是因为发送和接收在一台机子上面
        dgp = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("192.168.159.1"), 9998);
        dgs.send(dgp);

        //关闭资源
        dgs.close();
        System.out.println("A退出");
    }
}
  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-08-04 11:34:02  更:2021-08-04 11:34:26 
 
开发: 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:56:48-

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