什么是网络编程?
- 可以让设备中的程序与网络上的其他设备中的程序进行数据交互的技术(实现网络通信)。
基本的通信架构
- 基本的通信架构有两种形式:CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Service服务端)
1-网络编程三要素
1.1-IP
- IP(Internet Protocol)全称"互联网协议地址",是分配给上网设备的唯一标识。
- 目前,被广泛采用的IP地址有两种:IPv4、IPv6
IPv4
- IPv4是Internet Protocol version 4 的缩写,它使用32位地址,通常以点分十进制表示。
IPv6
- IPv6是Internet Protocol version 6的缩写,它使用128位地址,号称可以为地球上的每一粒沙子编号。
- IPv6分成8段,每段每四位编码成一个十六进制位表示,每段之间用冒号(:)分开,将这种方式称为冒分十六进制。
IP域名(Domain Name)
- 用于在互联网上识别和定位网站的人类可读的名称。
例如
DNS域名解析(Domain Name System)
- 是互联网中用于将域名转换为对应IP地址的分布式命名系统。它充当了互联网的"电话薄",将便于记忆的域名映射到数字化的IP地址,使得用户可以通过域名来访问网站和其他网络资源。
公网IP、内网IP、本机IP
- 公网IP:是可以连接到互联网的IP地址
- 内网IP:也叫局域网IP,是只能组织机构内部使用的IP地址;例如192.168.开头的就是常见的局域网地址,范围为192.168.0.0--192.168.255.255,专门为组织机构内部使用。
- 本机IP:127.0.0.1、localhost:代表本机IP,只会寻找当前程序所在的本机。
IP常用命令
- ipconfig:查看本机IP地址
- ping IP地址:检查网络是否连通。
InetAddress
代表IP地址。
1.1.1-InetAdress的常用方法
InetAddress
代表IP地址。
public static void main(String[] args) {
//目标:认识InetAddress类获取本机IP对象和对方ID对象。
try {
//1.获取本机IP对象
InetAddress ip1=InetAddress.getLocalHost();
System.out.println(ip1);
System.out.println(ip1.getHostName());
System.out.println(ip1.getHostAddress());
//2.获取对方ID对象
InetAddress ip2=InetAddress.getByName("www.baidu.com");
System.out.println(ip2);
System.out.println(ip2.getHostName());
System.out.println(ip2.getHostAddress());
//3.判断本机与对方主机是否互通
boolean reachable = ip2.isReachable(3000);//判断在3000毫秒内是否可以ping通
System.out.println(reachable);
} catch (Exception e) {
e.printStackTrace();
}
}
1.2-端口
- 作用:用来标记正在计算机设备上运行的应用程序,被规定为一个16位的二进制,范围是0~65535。
端口分类
- 周知端口:0~1023,被预先定义的知名应用占用(如:HTTP占用80,FTP占用21)。
- 注册端口:1024~49151,分配给用户进程或某些应用程序。
- 动态端口:49152~65535,之所以称为动态端口,是因为它一般不固定分配某种进程,而是动态分配。
- 注意:我们自己开发的程序一般选用注册端口,且一个设备中不能出现两个程序的端口号一样,否则报错。
1.3-协议
什么是通信协议?
- 网络上通信的设备,事先规定的连接,以及传输数据的规则被称为网络通信协议。
为了让全球所有上网设备都能互通互联,需要指定一套统一的标准
开放式网络互联标准:OSI网络参考模型
- OSI网络参考模型:全球网络互联标准
- TCP/IP网络模型:事实上的国际标准
传输层的两个协议
- UDP:用户数据报协议。
- TCP:传输控制协议。
UDP协议
- 特点:无连接、不可靠通信。
- 不事先建立连接,数据按照包发,一包数据包含:自己的IP、端口、目的地IP、端口和数据(限制在64KB内)等。
- 发送方不管对方是否在线,数据在中间丢失也不管,如果接受方受到数据也不返回确认,故是不可靠的。(一般常用于视频直播这种,因为这种丢一些也没关系。)
TCP协议
- 特点:面向连接、可靠通信。
- TCP的最终目的:要保证在不可靠的信道上实现可靠的数据传输。
- TCP主要有三个步骤实现可靠传输:三次握手 建立连接、传输数据进行确认,四次挥手断开连接。
三次握手建立可靠连接
- 可靠连接:确保通信双方收发消息都是没问题的(全双工模式)
四次挥手断开连接
- 目的:确保通信双方收发消息都已经完毕。
2-UDP通信
2.1-UDP快速入门
UDP协议
- 特点:无连接、不可靠通信。
- 不事先建立连接,数据按照包发,一包数据包含:自己的IP、端口、目的地IP、端口和数据(限制在64KB内)等。
- 发送方不管对方是否在线,数据在中间丢失也不管,如果接受方受到数据也不返回确认,故是不可靠的。(一般常用于视频直播这种,因为这种丢一些也没关系。)
- Java提供了一个Java.net.DatagramSocket类来实现UDP通信。
2.2-UDP协议的多发多收
客户端实现
- 创建DatagramSocket对象(发送端对象)
- 使用while死循环不断的接收用户的数据输入,如果用户输入的exit则退出程序
- 如果用户输入的不是exit, 把数据封装成DatagramPacket
- 使用DatagramSocket对象的send方法将数据包对象进行发送
- 释放资源
服务端实现
- 创建DatagramSocket对象并指定端口(接收端对象)→接韭菜的人
- 创建DatagramPacket对象接收数据(数据包对象)→韭菜盘子
- 使用DatagramSocket对象的receive方法传入DatagramPacket对象
- 使用while死循环不断的进行第3步
3-TCP通信
3.1-TCP快速入门
TCP协议
- 特点:面向连接、可靠通信。
- TCP的最终目的:要保证在不可靠的信道上实现可靠的数据传输。
- TCP主要有三个步骤实现可靠传输:三次握手 建立连接、传输数据进行确认,四次挥手断开连接。
- Java提供了一个java.net.Socket类来实现TCP通信。
3.1.1-TCP通信的实现一发一收:客户端开发
- 客户端程序就是通过java.net包下的Socket类来实现的。
public static void main(String[] args) throws Exception{
//目标:实现TCP通信下一发一收:客户端开发。
//1.创建Socket对象,请求与服务端的Socket连接。 可靠连接
Socket socket=new Socket(InetAddress.getLocalHost(),9999);
//2.从Socket通信管道中得到一个字节输出流。
OutputStream os = socket.getOutputStream();
//3.特殊数据流
DataOutputStream dos = new DataOutputStream(os);
dos.writeInt(1);
dos.writeUTF("你好,我是客户端");
//4.释放资源
socket.close();
}
3.1.2-TCP通信的实现一发一收:服务端开发
服务端是通过java.net包下的ServerSocket类来实现的。
public static void main(String[] args) throws Exception{
//目标:完成TCP通信一发一收:服务端开发。
System.out.println("==服务端启动了==");
//1.创建服务端ServerSocket对象(绑定端口号 监听客户端连接)
ServerSocket ss = new ServerSocket(9999);
//2.调用accept方法,阻塞等待客户端连接,一旦有客户端连接会返回一个Socket对象,代表和客户端通信的通道
Socket socket = ss.accept();
//3.获取输入流,读取客户端发送的数据
InputStream is = socket.getInputStream();
//4.把字节输入流包装成特殊数据输入流
DataInputStream dis = new DataInputStream(is);
//5.读取数据
int id = dis.readInt();
String msg = dis.readUTF();
System.out.println("id="+id+",收到的客户端消息msg:"+msg);
//6.客户端的ip地址和端口号
System.out.println("客户端的ip地址:"+socket.getInetAddress().getHostAddress());
System.out.println("客户端的端口号:"+socket.getPort());
}
3.2-TCP的多发多收
- 客户端使用死循环,让用户不断输入消息
- 服务端也使用死循环,控制服务端程序接收完消息后,继续去接收下一个消息。
3.3-同时接收多个客户端的消息
目前我们开发的服务端程序,是否可以支持同时与多个客户端通信?
- 不可以。
- 因为服务端现在只有一个主线程,只能处理一个客户端的消息。
- 这个时候我们就要引入多线程。