Java.net 这个包提供了,网络编程
网路通信
基本通信架构
CS架构(Client客户端/Server服务端)
client客户端 ---------------- Server服务端
Client客户端:
-
由程序员开发实现,客户端下载并且提供软件的运行(微信,qq,永结....)
-
及时更新与服务端保持同步。
-
客户端软件通常提供用户友好的界面,使得用户可以方便地与服务端进行交互。
-
客户端软件可以在各种设备上运行,如个人电脑、手机、平板电脑等。
-
客户端软件通常需要处理用户输入,并将其转换为服务端可以理解的请求。
Server服务端:
-
由程序员开发实现。
-
服务端通常运行在高性能的服务器上,处理来自各个客户端的请求。
-
服务端负责处理业务逻辑,如数据处理、存储、检索等。
-
服务端需要能够处理并发请求,即同时处理来自多个客户端的请求。
-
服务端需要具有良好的安全性,防止数据泄露或被恶意攻击。
B/S架构(Browser浏览器/Server服务器)
client客户端 ---------------- Browser浏览器 ----------------Server服务端
Client客户端:
-
网络连接和浏览器: 客户端主要需要提供网络连接功能,以便用户能够通过浏览器访问和使用应用程序。无需安装额外的应用程序,用户只需打开浏览器即可。
Browser浏览器:
-
用于访问应用程序: 浏览器是客户端的主要界面,用户通过浏览器访问应用程序的网页界面。可以使用常见的浏览器,如Chrome、Firefox、Safari等,或者在移动设备上使用内置的浏览器。
Server服务端:
-
Web服务器: 服务端需要提供Web服务器,以便响应客户端浏览器的请求,并提供相应的网页内容和功能。常见的Web服务器包括Apache、Nginx等。
-
应用程序后端: 服务端需要实现应用程序的后端逻辑,包括处理客户端请求、与数据库交互、业务逻辑处理等。可以使用各种后端技术和框架,如Node.js、Django、Spring Boot等。
-
数据存储: 服务端需要使用数据库或其他持久化存储方式,存储用户数据、应用程序状态等信息。常见的数据库包括MySQL、PostgreSQL、MongoDB等。
-
安全性和性能优化: 与传统客户端/服务器架构相似,服务端需要考虑安全性和性能优化,保护用户数据安全,提高系统的并发处理能力和性能稳定性。
基于浏览器的客户端和服务端开发通常采用Web开发技术,包括HTML、CSS、JavaScript等前端技术,以及各种后端技术和框架。通过Web开发,可以实现跨平台、跨设备的应用程序,并且用户无需安装任何额外的软件,只需打开浏览器即可使用。并且一定是当前最新的版本 .
网络通信三要素
ip地址
-
每个主机的唯一标识符
-
ipv4:32位二进制,分四段 每段8位 点(.)分十进制
-
ipv6:128位二进制,分八段 每段16位 冒(:)分十六进制
-
网页用的是域名,然后通过dns服务器来确定IP
-
公网IP,私网ip,专用ip,保留ip,回送IP(本地回环地址 127.0.0.1)
-
全0地址(通配符地址 0.0.0.0),广播地址(255.255.255.255),多播地址,APIPA
端口
-
每个程序的唯一标识符
-
当IP找到主机时,端口用于确定程序。从而实现程序的交流
-
16位的二进制 (0 - 65535)
-
专用/周知 端口(0 - 1023) 如 HTTP:80 FTP:21
-
注册端口(1024 - 49151) ,分配给任务程序的。指定的
-
动态端口(49152 - 65535),动态分配给任务程序,随机的。
协议
-
TCP(Transmission ControlProtocol)
-
传输控制协议
-
连接,可靠
-
-
UDP(User Dataaram Protocol)
-
用户数据报协议
-
无连接,不可靠。
-
编程
InetAddress
-
IP 地址,它不包含端口信息
方法 | 描述 |
---|---|
static InetAddress getLocalHost() | 获取本机ip相关信息,返回netAddress对象 |
static InetAddress getByName ( String host) | 根据指定ip / 域名,返回netAddress对象 |
String getHostName () | netAddress对象对应的主机名 |
String getHostAddress () | netAddress对象对应的ip |
boolean isReachable (int timeout) | 在指定毫秒内,判断本地主机是否与对方连通。 |
boolean isMulticastAddress () | 判断InetAddress对象是否为多播地址 |
boolean isLoopbackAddress () | 判断InetAddress对象是否为回环地址 |
boolean isLinkLocalAddress () | 判断InetAddress对象是否为链路本地地址 |
boolean isSiteLocalAddress () | 判断InetAddress对象是否为站点本地地址 |
InetSocketAddress:
-
它在内部使用一个 InetAddress 对象来存储 IP 地址,同时还存储了一个整数值来表示端口号。
-
未解析的套接字地址 : 不会尝试解析主机名,将主机名存储为字符串形式。在实际使用中,主机名将在需要时动态解析为 IP 地址。
方法 | 描述 |
---|---|
static InetSocketAddress createUnresolved (String host, int port) | 创建一个未解析的套接字地址,其中IP地址由主机名和端口号确定 |
void setAddress ( InetAddress addr) /getAddress | 设置InetSocketAddress对象对应的InetAddress |
void setHostName ( String hostname) /get... | 设置InetSocketAddress对象对应的主机名 |
void setPort (int port) /get | 设置InetSocketAddress对象对应的端口号 |
UDP(User Dataaram Protocol)
-
用户数据报协议
-
无连接,不可靠。
java.net.DatagramSocket
DatagramSocket 客户端/服务端创建
构造器 | 说明 |
---|---|
public DatagramSocket () | 一般创建客户端Socket对象,系统自动分配端口 |
public DatagramSocket (int port) | 一般创建服务端Socket对象,用户指定端口 |
DatagramSocket对象
方法 | 说明 |
---|---|
public void send ( DatagramPacket dp) | 发送数据报包 |
public void receive ( DatagramPacket p) | 接受数据报包 |
DatagramPacket数据报包创建
构造器 | 说明 |
---|---|
publc DatagramPacket ( byte []buf,int length,InetAddress,int port ) | 一般用于创建发送出去的数据报包 |
public DatagramPacket (byte []buf , int length) | 一般用于创建接受数据的数据报包 |
DatagramPacket对象
-
操作系统会自动将数据报发送到指定的目标地址和端口,同时将发送方的 IP 地址和端口号添加到网络包的头部。
-
如果这个数据报包是接受到的,那么这个数据报包,会携带对方的ip信息
方法 | 说明 |
---|---|
int getLength () | 获取接受到的数据报包的长度 |
InetAddress getAddress() /set... | 获取数据报包的中的地址 |
int getPort() /set... | 获取数据报包的中的端口号 |
byte[] getData() /setData() | 获取数据报包的数据内容 |
代码演示
//client 文件 客户端程序 package org.example; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class client { public static void main(String[] args) throws Exception { //UDP 客户端 DatagramSocket socket = new DatagramSocket(); //发送的数据 String msg = "Hello world!"; //打包成数据包,指定目标地址和端口 DatagramPacket packet = new DatagramPacket(msg.getBytes(), msg.getBytes().length, InetAddress.getByName("localhost"), 28256); //发送数据包 socket.send(packet); } } //service文件 服务端程序 package org.example; import java.net.DatagramPacket; import java.net.DatagramSocket; public class service { public static void main(String[] args) throws Exception { //UDP 服务端 DatagramSocket socket = new DatagramSocket(28256); //接收数据包 DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); while(true) { //等待接收数据 socket.receive(packet); //解析数据 String msg = new String(packet.getData(), 0, packet.getLength()); //打印数据 System.out.println(packet.getAddress().getHostAddress() + ":" + packet.getPort() + msg); /** * 1. packet.getData() 返回byte[] * 2. packet.getLength() 返回int * 3. packet.getPort() 返回int * 4. packet.getAddress() 返回InetAddress * 5. packet.getAddress().getAddress() 返回byte[] * 6. packet.getAddress().getHostAddress() 返回String */ } } }
TCP(Transmission ControlProtocol)
-
传输控制协议
-
连接,可靠
Socket客户端的创建
构造器 | 说明 |
---|---|
publc Socket(String host,int port) | 指定服务器ip 和端口,并请求与服务器建立连接,连接通过,获得客户端对象 |
Socket对象
-
一般将流包装成Data.......流
方法 | 说明 |
---|---|
public OutputStream getOutputStream () | 获得字节是输出流,用于流出数据。 注意当流关闭时(调用流的close())Socket连接也会关闭。 如果采用Socket对象socket.shutdownOutput(), 来关闭输出流,时Socket不会关闭,但是后面的就不可以创建输出流了; |
public InputStream getInputStream() | 获得字节是输入流,用于流入数据。流入时会阻塞住等待数据流入。 注意当流关闭时Socket连接也会关闭 如果采用Socket对象socket.shutdownInput(), 来关闭输入流,时Socket不会关闭,但是后面的就不可以创建输入流了; |
ServiceSocket客户端的创建
构造器 | 说明 |
---|---|
publc Socket(int port) | 为本地服务器设置端口 |
public Socket accept() | 阻塞式等待客户端的连接,一旦连接就会返回服务端的Socket对象 这个对象和 客户端的Socket对象用tcp方式连接着 |
代码演示
//客户端程序------------------------------ import java.io.*; import java.net.Socket; public class clientTest { public static void main(String[] args) throws IOException, InterruptedException { //建立TCP连接的客户端 Socket socket = new Socket("127.0.0.1",2825); //阻塞等带连接 //获得一个字节输出流 OutputStream os= socket.getOutputStream(); //os包装成数据输出流 DataOutputStream dos = new DataOutputStream(os); //查看是否连接成功 System.out.println(socket.isConnected()); dos.writeUTF("123456 "); //刷新缓冲区 dos.flush(); //关闭流 dos.close(); //关闭连接 socket.close(); } } //服务端程序-------------------------------------------------- import java.io.*; import java.net.ServerSocket; import java.net.Socket; public class ServerTest { public static void main(String[] args) throws Exception { //建立TCP连接的服务端 ServerSocket server = new ServerSocket(2825); //等待客户端连接 Socket socket = server.accept(); //阻塞等待连接 //获得一个字节输入流 InputStream is = socket.getInputStream(); //is包装成数据输入流 DataInputStream dis = new DataInputStream(is); DataInputStream dis2 = new DataInputStream(is); //不会报错,但是要注意的是,这两个流是共享的,所以如果在一个流中读取了数据,另一个流再读取数据时,会读取不到数据 //查看是否连接成功 System.out.println((!socket.isConnected() || socket.isClosed())); //读取数据 System.out.println(dis.readUTF()); //关闭流 dis.close(); //关闭连接 socket.close(); } }