java关于⽹络编程

⽹络编程

所谓⽹络编程,指的就是在同⼀个⽹络中不同机器之间的通信

计算机之间通信需要的条件

IP地址

IP地址指的是互联⽹地址(Internet Protocol Address ) ,是联⽹设备与互联⽹之间的唯⼀标识,在同⼀个⽹段中,IP地址是唯⼀的
IP地址是数字型的,是⼀个32位的整数,通常将其分成4个8位的⼆进制数,每8位之
间⽤圆点隔开, 每个8位整数可以转换为⼀个0~255的⼗进制整数,例如:202.9.128.88
标准分类:分为IPV4和IPV6
IP地址使⽤范围分类
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地址可以唯⼀的确定⽹络上的⼀个通信实体,但⼀个通信实体可以有多个通信程序
同时提供⽹络服务,此时还需要使⽤端⼝

端⼝

数据的发送和接收都需要通过端⼝出⼊计算机,端⼝号⽤于唯⼀标识通信实体上进⾏⽹络通讯的程序,同⼀台机器上不能两个程序占⽤同⼀个端⼝
端⼝号的取值范围:0~65535
端⼝分类:
公认端⼝:0~1023
注册端⼝:1025~49151
动态或私有端⼝:1024~65535
常⽤端⼝:
mysql:3306
oracle:1521
tomcat:8080

通信协议

需要通信的设备之间需要实现相同的通信协议
⽹络分层(七层协议):物理层,数据链路层,⽹络层,传输层,会话层,表示层,应⽤层
通信协议分类:
传输层协议:TCP和UDP
⽹络层IP协议:IPV4和IPV6,互联⽹协议

应⽤层协议:HTTP

七层协议:
应⽤层
与其它计算机进⾏通讯的⼀个应⽤,它是对应应⽤程序的通信服务的。 例如,⼀个没有通信功能的字处理程序就不能执⾏通信的代码, 从事字处理⼯作的程序员也不关⼼OSI的第7层。但是,如果添加了⼀个 传输⽂件的选项,那么字处理器的程序员就需要实现OSI的第7层。 示例:TELNET,HTTP,FTP,NFS,SMTP等。
表示层
这⼀层的主要功能是定义数据格式及加密。例如,FTP允许你选择以⼆进制 或ASCII格式传输。如果选择⼆进制,那么发送⽅和接收⽅不改变⽂件的内容。 如果选择ASCII格式,发送⽅将把⽂本从发送⽅的字符集转换成标准的ASCII后 发送数据。在接收⽅将标准的ASCII转换成接收⽅计算机的字符集。示例:加密,ASCII等。
会话层
它定义了如何开始、控制和结束⼀个会话,包括对多个双向消息的控制和管理, 以便在只完成连续消息的⼀部分时可以通知应⽤,从⽽使表示层看到的数据是连续的,在某些情况下,如果表示层收到了所有的数据,则⽤数据代表表示层。示例:RPC,SQL等。
传输层
这层的功能包括是否选择差错恢复协议还是⽆差错恢复协议,及在同⼀主机上对不同应⽤的数据流的输⼊进⾏复⽤,还包括对收到的顺序不对的数据包的重新排序功能。示例:TCP,UDP,SPX。
⽹络层
这层对端到端的包传输进⾏定义,它定义了能够标识所有结点的逻辑地址,还定义了路由实现的⽅式和学习的⽅式。为了适应最⼤传输单元⻓度⼩于包⻓度的传输介质,⽹络层还定义了如何将⼀个包分解成更⼩的包的分段⽅法。示例:IP,IPX等。
数据链路层
它定义了在单个链路上如何传输数据。这些协议与被讨论的各种介质有关。示例:ATM,FDDI等。

物理层
OSI的物理层规范是有关传输介质的特性标准,这些规范通常也参考了其他组织制定的标准。 连接头、帧、帧的使⽤、电流、编码及光调制等都属于各种物理层规范中的内容。 物理层常⽤多个规范完成对所有细节的定义。示例:Rj45,802.3等。

客户端和服务器

客户端:可以让⽤户直接交互,⽤来访问服务器端
服务器端:给⽤户提供数据的存储,数据的中转,数据的运算
注意:
1.客户端服务器端都是指的是应⽤(app),⽽⾮主机,即 客户端!=主机 服务器端!=主机
2.⼀台主机上可以同时运⾏多个应⽤
3.⼀台主机上可以同时存储客户端和服务器端,也可以分属于不同的主机
4.应⽤就是⼀个进程,所以客户端和服务器端都是独⽴的进程
如下图展示:

在这里插入图片描述

案例展示:

在这里插入图片描述

⽹址理解

⽹址案例: “https://www.baidu.com:80/ewf/sdf?name=bingbing&age=20”
⽹址的功能:实现客户端与服务器端的通信
协议:是制定⼀个统⼀的规范
http协议:超⽂本传输协议,实现的是⽹络间的通信的⼀个通信规则
https协议:安全的http协议—可以省略,默认是http协议
域名/IP:标记⽹络上的唯⼀⼀台主机 可以简化写:baidu
端⼝号:标记同⼀台主机上的某⼀个服务器 [0,65536]—可以省,默认80
资源路径: 可以省
查询条件: 可以省

⽹络相关概念

1.外⽹:IP是唯⼀性,不能重复。范围:0.0.0.0~255.255.255.255
2.内⽹:通过路由器或者交换器设备,来重新设置IP地址。
不同的内⽹的ip可以相同。内⽹A的某⼀台主机通过⾃⼰的⽹卡与⾃⼰的路由器A通信,然后路由器A通过⽹络中⼼与路由器B通信,路由器B再与内⽹中的某⼀台机器的⽹卡通信。

3.IP: ip地址是确定⼀台机器的唯⼀标识符
4.NETMASK(⼦⽹掩码):与ip连⽤,⽤于确定⽹络段位 192.168.1.x 范围:1-254 255.255.255.0
⼦⽹掩码有1的位置对应ip的部分就是⽹络段位。0对应的位置就是内⽹中主机的位置。⼦⽹掩码作⽤:⽤来指定当前机器属于哪个ip号段的判断⽅式:将当前的ip的⼆进制按位与⼦⽹掩码的⼆进制等于⽹段地址
如: 192.168.1.2 & 255.255.255.0 = 192.168.1.0
5.GATEWAY:⽹关,⽤于与连接外⽹的机器设备通信(路由器)换句话说,⽹关就是路由器的IP
6.DNS:域名解析服务器 119.75.217.109 www.baidu.com

域名解析器
在这里插入图片描述

设备介绍

1.路由器
路由器是连接两个或多个⽹络的硬件设备,在⽹络间起⽹关的作⽤,是读取每⼀个数据包中的地址然后决定如何传送的专⽤智能性的⽹络设备。它能够理解不同的协议,例如某个局域⽹使⽤的以太⽹协议,因特⽹使⽤的TCP/IP协议。这样,路由器可以分析各种不同类型⽹络传来的数据包的⽬的地址,把⾮TCP/IP⽹络的地址转换成TCP/IP地址,或者反之;再根据选定的路由算法把各数据包按最佳路线传送到指定位置。所以路由器可以把⾮TCP/ IP⽹络连接到因特⽹上。
2.交换机
交换机(Switch)意为“开关”是⼀种⽤于电(光)信号转发的⽹络设备。它可以为接⼊交换机的任意两个⽹络节点提供独享的电信号通路。最常⻅的交换机是以太⽹交换机。其他常⻅的还有电话语⾳交换机、光纤交换机等。
3.Modem
调制解调器(英⽂名Modem),俗称“猫”,是⼀种计算机硬件.它能把计算机的数字信号翻译成可沿普通电话线传送的脉冲信号,⽽这些脉冲信号⼜可被线路另⼀端的另⼀个调制解调器接收,并译成计算机可懂的语⾔。计算机内的信息是由“0”和“1”组成数字信号,⽽在电话线上传递的却只能是模拟电信号。于是,当两台计算机要通过电话线进⾏数据传输时,就需要⼀个设备负责数模的
转换。
4.虚拟机
虚拟机(Virtual Machine)指通过软件模拟的具有完整硬件系统功能的、运⾏在⼀个完全隔离环境中的完整计算机系统。在实体计算机中能够完成的⼯作在虚拟机中都能够实现。在计算机中创建虚拟机时,需要将实体机的部分硬盘和内存容量作为虚拟机的硬盘和内存容量。每个虚拟机都有独⽴的CMOS、硬盘和操作系统,可以像使⽤实体机⼀样对虚拟机进⾏操作。

相关类的使⽤

InetAddress类

Java提供了InetAddress类来代表ip地址,是对ip地址的抽取和封装,有两个⼦类:Inet4Address,Inet6Address,分别表示IPv4和IPv6
常⽤⽅法:

//1.获取主机:主机名称和ip地址
/**
* static InetAddress getLocalHost()
返回本地主机。
*/
InetAddress id1 = null;
try {
	id1 = InetAddress.getLocalHost();
	//USER-VG9EDR1SST/10.31.165.42
	System.out.println(id1);
} catch (UnknownHostException e) {
// 未知的主机
	e.printStackTrace();
}
//2.获取ip地址的字符串表示形式
/**
* String getHostAddress()
返回 IP 地址字符串(以⽂本表现形式)。
*/
String str1 = id1.getHostAddress();
System.out.println(str1);//10.31.165.42
//3.获取主机名
/**
* String getHostName()
获取此 IP 地址的主机名。
*/
String str2 = id1.getHostName();
System.out.println(str2);
//4.根据主机或者ip地址获取InetAddress对象
/**
* static InetAddress getByName(String host)
在给定主机名的情况下确定主机的 IP 地址。
*/

URLEncoder类和URLDecoder类

​ URLEncoder类和URLDecoder类⽤于完成普通字符串和application/x-www-form-urlencoded MIME字符串之间的转换

    //%E5%8D%83%E9%94%8B
    //URLDecoder:解码,将特殊中⽂字符串转换为普通字符串
    String string1 = URLDecoder.decode("%E5%8D%83%E9%94%8B",
    "utf-8");
    System.out.println(string1);
    //URLEncoder:编码,将普通字符串转换为特殊字符串
    String string2 = URLEncoder.encode("Java的开发指南",
    "GBK");
    System.out.println(string2);
    //注意:编码和解码需要采⽤相同的字符集
    String string3 = URLDecoder.decode(string2, "utf-8");
    System.out.println(string3);

基于TCP的⽹络编程

概念

TCP,Transmission Control Protocol,传输控制协议,基于字节流的传输层通信协议
特点:
a.安全的
b.⾯向连接的
c.效率低
d.传输数据⼤⼩限制,⼀旦连接建⽴,双⽅可以按统⼀的格式传输⼤的数据TCP的三次握⼿
a.客户端向服务端发送⼀个请求
b.服务端收到请求后,回客户端⼀个响应
c.客户端向收到服务端的响应后,回服务端⼀个确认信息

Socket通信模型

在这里插入图片描述

Socket和ServerSocket

客户端发送消息,服务端接收消息

客户端

package test;

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

public class Client {
    public static void main(String[] args) {
        Socket socket = null;

        try {
            socket = new Socket(InetAddress.getByName("127.0.0.1"), 7777);
            PrintStream pw = new PrintStream(socket.getOutputStream());
            pw.println("hello handsome boy");
            pw.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

服务端

package test;

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

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket =null;

        try {
            serverSocket = new ServerSocket(7777);

            Socket socket = serverSocket.accept();

            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            //InputStream inputStream = socket.getInputStream();
            String s = br.readLine();
            System.out.println(s);
            br.close();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            serverSocket.close();
        }
    }
}

多个客户端和⼀个服务端通信

客户端

package test;

import java.io.*;
import java.net.Socket;
import java.util.Scanner;

public class Client1 {
    public static void main(String[] args) throws IOException {
        /**
         * 1.客户端对象
         * 2.通过客户端向服务端发送消息【socket.getOutputStream()】
         * 3.接收服务端回复的消息【socket.getInputStream()】
         * 4.借助于Scanner
         * 5.循环的发送和接收消息【进⾏约定:bye/886则break出循环】
         * 6.释放资源
         */
        //1.构建客户端的对象
        Socket socket = null;
        try {
            socket = new Socket("127.0.0.1",6666);
            PrintStream ps = new PrintStream(socket.getOutputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            Scanner scanner = new Scanner(System.in);
            while (true){
                System.out.print("客户端说:");
                String s = scanner.nextLine();
                ps.println(s);
                ps.flush();

                System.out.print("收到的消息为:");
                String s1 = br.readLine();
                System.out.println(s1);

                if (s1.equals("bye")){
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            socket.close();
        }
    }
}

服务端

package test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;

public class Server1 {
    static Set<Socket> list = new HashSet<>();
    public static void main(String[] args) {
        /**
         * 1.创建服务端对象
         * 2.通过循环,为不同的客户端进⾏服务
         * 3.循环体内,创建线程
         * 4.线程的执⾏体中,进⾏发送消息和接收消息的操作
         * 读取客户端发送来的消息【socket.getInputStream()】
         * 回复给客户端的消息【socket.getOutputStream()】
         * 5.进⾏约定:何时停⽌循环
         * 6.释放资源
         * */
        ServerSocket serverSocket = null;
        try {
            serverSocket = new ServerSocket(6666);
            while (true) {
                Socket socket = serverSocket.accept();
                list.add(socket);
                new Thread(new ServerThread(socket)).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
class ServerThread implements Runnable{
    private Socket socket;

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

    @Override
    public void run() {
        try {
            PrintStream ps = new PrintStream(socket.getOutputStream());
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            Scanner scanner = new Scanner(System.in);
            while (true){
                System.out.print("客户端说:");
                String s = br.readLine();
                System.out.println(s);
                System.out.print("服务端回复:");
                String s1 = scanner.nextLine();
                for (Socket so : Server1.list) {
                    if (so == socket){
                        ps.println(s1);
                    }
                }
                ps.flush();
                if (s1.equals("bye")){
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}

UDP编程

概念
User Datagram Protocol的简称,⽤户数据包协议,提供⾯向事务的简单不可靠信息传送服务
特点:
a.不安全

b.⽆连接
c.效率⾼
d.UDP传输数据时是有⼤⼩限制的,每个被传输的数据报必须限定在64KB之内

DatagramSocket和DatagramPacket

发送方

package test;

import java.io.IOException;
import java.net.*;

public class Sender {
    public static void main(String[] args) {
        sendMessage("127.0.0.1",6666,"how are you");
    }
    /**
     * 发送数据
     * @param ip 指定接收⽅的ip地址
     * @param port 指定接收⽅的端⼝号
     * @param message 需要发送的信息
     */
    public static void sendMessage(String ip,int port,String message){
        DatagramSocket socket = null;

        try {
            socket = new DatagramSocket();
            //2.将需要发送的数据封装为数据报包
            /**
             * DatagramPacket(byte[] buf, int length,
             InetAddress address, int port)
             构造数据报包,⽤来将⻓度为 length 的包发送到指定主机上的指定端
             ⼝号。
             */
            DatagramPacket packet = new DatagramPacket(message.getBytes(),message.length(),
                    InetAddress.getByName(ip),port);
            socket.send(packet);
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

接收方

package test;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;

public class Receiver {
    public static void main(String[] args) {
        //1.实例化DatagramSocket的对象
        //需要进⾏绑定端⼝号:由发送⽅发送来的端⼝号进⾏决定
        /**
         * DatagramSocket(int port)
         创建数据报套接字并将其绑定到本地主机上的指定端⼝。
         */
        DatagramSocket socket = null;
        try {
            socket = new DatagramSocket(6666);
            //2.将接收到的数据封装到数据报包中
            /**
             * DatagramPacket(byte[] buf, int length)
             构造 DatagramPacket,⽤来接收⻓度为 length 的数据包。
             */
            byte[] arr = new byte[1024];
            DatagramPacket packet = new DatagramPacket(arr, args.length);
            System.out.println("等待接受数据");
            //3.接收数据
            /**
             * void receive(DatagramPacket p)
             从此套接字接收数据报包。
             */
            //注意:将数据从⽹络中读取出来
            socket.receive(packet);
            //4.获取发送⽅的详细信息
            //信息
            /**
             * byte[] getData()
             返回数据缓冲区。
             */
            byte[] message = packet.getData();
            String result = new String(message, 0, message.length);
            //获取发送⽅的ip地址
            /**
             * InetAddress getAddress()
             返回某台机器的 IP 地址,此数据报将要发往该机器或者是从该机器接收
             到的。
             */
            InetAddress address = packet.getAddress();
            String ip = address.getHostAddress();
            //获取消息是从发送发的哪个端⼝号发出来的
            /**
             * int getPort()
             返回某台远程主机的端⼝号,此数据报将要发往该主机或者是从该主机接
             收到的。
             */
            int port = packet.getPort();
            System.out.println(ip + ":" + port + "说:" + result);
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

RPC

什么是RPC

RPC, 远程过程调⽤(Remote Procedure Call,RPC)是⼀个计算机通信协议,该协议允许运⾏于⼀台计算机的程序程调⽤另⼀台计算机的上的程序。通俗讲,RPC通过把⽹络通讯抽象为远程的过程调⽤,调⽤远程的过程就像调⽤本地的⼦程序⼀样⽅便,从⽽屏蔽了通讯复杂性,使开发⼈员可以⽆需关注⽹络编程的细节,将更多的时间和精⼒放在业务逻辑本身的实现上,提⾼⼯作效率

RPC本质上是⼀种 Inter-process communication(IPC)——进程间通信的形式。常⻅的进程间通信⽅式如管道、共享内存是同⼀台物理机上的两个进程间的通信,⽽RPC就是两个在不同物理机上的进程之间的通信。概括的说,RPC就是在⼀台机器上调⽤另⼀台机器上的⽅法,这种调⽤在远程机器上对代码的执⾏就像在本机上对代码的执⾏⼀样,只是迁移了⼀个执⾏环境⽽已。

举例

在这里插入图片描述

1.客户端client发起服务调⽤请求。

2.client stub 可以理解成⼀个代理,会将调⽤⽅法、参数按照⼀定格式进⾏封装,通
过服务提供的地址,发起⽹络请求。
3.消息通过⽹络传输到服务端。
4.server stub接受来⾃socket的消息
5.server stub将消息进⾏解包、告诉服务端调⽤的哪个服务,参数是什么
6.结果返回给server stub。
7.sever stub把结果进⾏打包交给socket
8.socket通过⽹络传输消息
9.client slub 从socket拿到消息。
10.client stub解包消息将结果返回给client。
⼀个RPC框架就是把步骤2到9都封装起来。

.简述UDP和TCP之间的区别(面试题)

TCP								 UDP
0.传输的是流				 			传输的是包
1.是建⽴在连接的基础上				 建⽴在⾮连接的基础上
2.安全性更⾼ 						安全性低
3.传输速度低 						速度⾼
4.适合传输数据量⼤的数据 				数据量⼩的数据
5.适合点对点通信 					   适合⼴播

存中…(img-H2f86JxZ-1628910223476)]

1.客户端client发起服务调⽤请求。

2.client stub 可以理解成⼀个代理,会将调⽤⽅法、参数按照⼀定格式进⾏封装,通
过服务提供的地址,发起⽹络请求。
3.消息通过⽹络传输到服务端。
4.server stub接受来⾃socket的消息
5.server stub将消息进⾏解包、告诉服务端调⽤的哪个服务,参数是什么
6.结果返回给server stub。
7.sever stub把结果进⾏打包交给socket
8.socket通过⽹络传输消息
9.client slub 从socket拿到消息。
10.client stub解包消息将结果返回给client。
⼀个RPC框架就是把步骤2到9都封装起来。

.简述UDP和TCP之间的区别(面试题)

TCP								 UDP
0.传输的是流				 			传输的是包
1.是建⽴在连接的基础上				 建⽴在⾮连接的基础上
2.安全性更⾼ 						安全性低
3.传输速度低 						速度⾼
4.适合传输数据量⼤的数据 				数据量⼩的数据
5.适合点对点通信 					   适合⼴播
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值