一、网络编程基本概念
1、网络编程
可以让设备中的程序与网络上其他设备中的程序进行数据交互的技术(实现网络通信)。
2、基本的通信架构
基本的通信架构有2种形式:
CS架构(Client客户端/Server服务端)、BS架构(Browser浏览器/Server服务端)
Clients-Server(CS)架构
Browser-Server(BS)架构
无论是CS架构,还是BS架构的软件都必须依赖网络编程!
Java提供了哪些网络编程解决方案?java.net.*包下提供了网络编程的解决方案!
二、网络编程三要素
1、IP地址
IP(Internet Protocol):全称”互联网协议地址”,是分配给上网设备的唯一标识。
目前,被广泛采用的IP地址形式有两种:IPv4、IPv6。
IPv4
IPv4是Internet Protocol version 4的缩写,它使用32位地址,通常以点分十进制表示。
IPv6
IPv6是Internet Protocol version 6的缩写,它使用128位地址,号称可以为地球上的每一粒沙子编号。
IPv6分成8段,每段每四位编码成一个十六进制位表示, 每段之间用冒号(:)分开,将这种方式称为冒分十六进制。
IPv4的地址分类形式
公网地址(万维网使用)和私有地址(局域网使用)。
192.168,开头的就是私有地址,范围即为192.168.0.0--192.168.255.255
专门为组织机构内部使用,以此节省IP
路由器分配公网IP,然后路由器为主机分配192.168的网络
特殊IP地址
127.0.0.1,也可以是localhost:是回送地址也称本地回环地址,也称本机IP,永远只会寻找当前所在本机。
常用CMD命令
ipconfig:查看本机IP地址
ping:检查网络是否连通
InetAddress类
static InetAddress getByName(String host) 确定主机名称的IP地址(主机名称可以是机器名称,也可以是IP地址) String getHostName() 获取此 IP 地址的主机名 String getHostAddress() 返回文本显示中的 IP 地址字符串package com.itheima.net; import java.net.InetAddress; import java.net.UnknownHostException; public class InetAddressDemo { /* static InetAddress getByName(String host) 确定主机名称的IP地址(主机名称可以是机器名称,也可以是IP地址) String getHostName() 获取此 IP 地址的主机名 String getHostAddress() 返回文本显示中的 IP 地址字符串 */ public static void main(String[] args) throws UnknownHostException { // 将需要操作的ip或者是主机名封装为 InetAddress对象. InetAddress byName = InetAddress.getByName("ys"); System.out.println(byName); // 获取此 IP 地址的主机名 System.out.println(byName.getHostName()); // 返回文本显示中的 IP 地址字符串 System.out.println(byName.getHostAddress()); } }2、端口
端口号应用程序在设备中唯一的标识。
端口号:由两个字节表示的整数,取值范围:0~65535
其中0~1023之间的端口号用于一些知名的网络服务或者应用。
我们自己使用1024以上的端口号就可以了。
注意:一个端口号只能被一个应用程序使用
3、协议
计算机网络中,连接和通信的规则被称为网络通信协议
UDP协议
用户数据报协议(UserDatagramProtocol) UDP是面向无连接通信协议。
速度快,有大小限制一次最多发送64K,数据不安全,易丢失数据
TCP协议
传输控制协议TcP(TransmissionControlProtocol) TCP协议是面向连接的通信协议。
速度慢,没有大小限制,数据安全。
三、UDP协议收发数据
发送端:
创建发送端的DatagramSocket对象
数据打包(DatagramPacket)
发送数据
释放资源
package com.itheima.udp; import java.net.*; public class Send { public static void main(String[] args) throws Exception { // 1. 创建发送端的DatagramSocket对象 (发送端的驿站) // DatagramSocket socket = new DatagramSocket(); 随机绑定端口 DatagramSocket socket = new DatagramSocket(8888); // 2. 准备发送的数据 String msg = "你好"; byte[] bytes = msg.getBytes();//将数据转化为字节数组 // 3. 将数据打包 DatagramPacket packet = new DatagramPacket(bytes, bytes.length, InetAddress.getByName("127.0.0.1"), 9999);//接收端的端口号 // 4. 发送数据 socket.send(packet); // 5. 释放资源 socket.close(); } }接收端:
创建接收端的DatagramSocket对象
接收打包好的数据
解析数据包
释放资源
package com.itheima.udp; import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class Receive { public static void main(String[] args) throws IOException { // 1. 创建接收端的DatagramSocket对象 (接收端的驿站) DatagramSocket socket = new DatagramSocket(9999); // 2. 准备接收端的包裹对象 DatagramPacket packet = new DatagramPacket(new byte[1024], 1024); // 3. 接受数据 System.out.println(1); socket.receive(packet);//阻塞效果,等待发送端发送数据 System.out.println(2); // 4. 拆包裹 byte[] data = packet.getData(); String msg = new String(data, 0, packet.getLength());//把有效字节数组转化为字符串 String ip = packet.getAddress().getHostAddress(); System.out.println("接收到" + ip + "发送的数据为:" + msg); // 5. 释放资源 socket.close(); } }四、TCP协议收发数据
TCP 协议是面向连接的通信协议
速度慢,没有大小限制,数据安全
通过三次握手建立连接
通过四次挥手断开连接
客户端:
1.创建Socket对象指定ip和端口Socket (String host,int port)
2.通过socket对象获取传输数据的流对象
OutputStream getoutputStream()
Inputstream getInputstream()
3.通过流对象收发数据
4.释放资源
package com.itheima.tcp; import java.io.*; import java.net.Socket; public class Client { public static void main(String[] args) throws IOException { // 使用File对象, 封装要上传的文件 File src = new File("D:\\2.jpg"); // 1. 创建客户端的站点指定服务端的ip和端口 Socket socket = new Socket("localhost", 8899); // 2. 客户端通过socket获取传输数据的输入输出流 InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); // 3. 客户端创建本地的流对象, 读取要上传的文件 FileInputStream fis = new FileInputStream(src); byte[] bys = new byte[1024]; int len; while((len = fis.read(bys)) != -1){ // 重点: 将读取到的字节, 通过网络流对象, 写出给服务端 os.write(bys, 0, len); } // 客户端给服务端结束的标记,制造-1的标记 socket.shutdownOutput(); fis.close(); // 4. 读取服务端发送回来的消息 (上传成功) byte[] data = new byte[1024]; int dataLength = is.read(data); String msg = new String(data, 0, dataLength);//转换为字符串 System.out.println("读取到服务的消息为:" + msg); // 5. 关闭流, 释放资源 is.close(); os.close(); socket.close(); } }服务端:
1.创建ServerSocket对象指定端口
ServerSocket(int port)
2.响应客户端发送的请求
Socket accept ()
3.通过socket对象获取传输数据的流对象
OutputStreamgetoutputStream ()
InputStream getInputStream ()
4.通过流对象收发数据
5.释放资源
package com.itheima.tcp; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.ServerSocket; import java.net.Socket; public class Server { public static void main(String[] args) throws IOException { // 1. 创建ServerSocket对象 ServerSocket server = new ServerSocket(8899); System.out.println("服务端开启, 等待客户端连接..."); // 2. 响应客户端发送的请求 Socket socket = server.accept(); System.out.println("响应成功!"); // 3. 服务端通过socket获取传输数据的输入输出流 InputStream is = socket.getInputStream(); OutputStream os = socket.getOutputStream(); // 本地字节输出流 FileOutputStream fos = new FileOutputStream("E:\\result.jpg"); // 4. 读取客户端发送过来的文件 (图片的字节) byte[] bys = new byte[1024]; int len; while ((len = is.read(bys)) != -1) { fos.write(bys, 0, len); } fos.close(); // 5. 写出上传成功的消息给客户端 os.write("上传成功".getBytes()); // 6. 关闭流, 释放资源 is.close(); os.close(); socket.close(); } }