Java基础_网络编程
- 网络编程三要素
- InetAddress
- 网络模型
- UDP通信程序
- 单播
- 发送数据
- 接收数据
- 聊天室
- 组播
- 广播
- TCP
- TCP通信程序
- 三次握手和四次挥手
- 来源
- Gitee地址
网络编程三要素
- IP: 设备在网络中的地址,是唯一的标识
- 端口号: 应用程序在设备中唯一的标识。
- 协议: 数据在网络中传输的规则,常见的协议有UDP、TCP、http、https、ftp。
InetAddress
public class demo {
public static void main(String[] args) throws UnknownHostException {
/**
* static InetAddress getByName(String host) 确定主机名称的IP地址。主机名称可以是机器名称,也可以是IP地址
* String getHostName() 获取此IP地址的主机名
* String getHostAddress() 返回文本显示中的IP地址字符串
*/
// 1. 获取InetAddress的对象
InetAddress address = InetAddress.getByName("cen");
System.out.println(address);
String hostName = address.getHostName();
System.out.println(hostName); // cen
String hostAddress = address.getHostAddress();
System.out.println(hostAddress); // 192.168.174.1
}
}
网络模型
- OSI参考模型:世界互联协议标准,全球通信规范,单模型过于理想化,未能在因特网上进行广泛推
- TCP/IP参考模型(或TCP/IP协议):事实上的国际标准。
UDP通信程序
单播
发送数据
public class Demo {
public static void main(String[] args) throws IOException {
/**
* udp发送数据
*/
// 1. 创建DatagramSocket对象
// 绑定发送端口
// 空参: 所有可用端口中随机一个进行使用
// 有参: 指定端口
DatagramSocket ds = new DatagramSocket();
// 2. 打包数据
String str = "Hello Socket!";
byte[] bytes = str.getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 10086;
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
// 3. 发送数据
ds.send(dp);
// 4. 释放资源
ds.close();
}
}
接收数据
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
/**
* udp接收数据
*/
// 1. 创建DatagramSocket对象
// 接收时要绑定端口
DatagramSocket ds = new DatagramSocket(10086);
// 2. 接收数据
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);
// 3. 解析数据
byte[] data = dp.getData();
int len = dp.getLength();
InetAddress address = dp.getAddress();
int port = dp.getPort();
System.out.println("接收到数据: " + new String(data, 0, len));
System.out.println("该数据是从" + address + "的" + port + "端口发出的");
// 4. 释放资源
ds.close();
}
}
聊天室
// SendDemo
public class SendDemo {
public static void main(String[] args) throws IOException {
/**
* udp循环发送数据, 直到输入886, 停止发送
*/
DatagramSocket ds = new DatagramSocket();
Scanner sc = new Scanner(System.in);
// 循环发送数据
while(true) {
String str = sc.nextLine();
if(str.equals("886")){
break;
}
byte[] bytes = str.getBytes();
InetAddress address = InetAddress.getByName("127.0.0.1");
int port = 10086;
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
ds.send(dp);
}
ds.close();
}
}
// ReceiveDemo
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
/**
* udp循环接收数据
*/
DatagramSocket ds = new DatagramSocket(10086);
while(true) {
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ds.receive(dp);
byte[] data = dp.getData();
int len = dp.getLength();
InetAddress address = dp.getAddress();
int port = dp.getPort();
System.out.println("接收到数据: " + new String(data, 0, len));
System.out.println("该数据是从" + address + "的" + port + "端口发出的");
}
}
}
组播
- 组播地址: 224.0.0.0 ~ 239.255.255.255, 其中224.0.0.0 ~ 224.0.0.255为预留的组播地址
// Send
public class SendDemo {
public static void main(String[] args) throws IOException {
/**
* 组播发送
*/
// 1. 创建MulticastSocket对象
MulticastSocket ms = new MulticastSocket();
// 2. 创建DatagramPacket对象
String str = "Hello MultiSocket!";
byte[] bytes = str.getBytes();
InetAddress address = InetAddress.getByName("224.0.0.1");
int port = 10000;
DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, port);
// 3. 发送数据
ms.send(dp);
// 4. 释放资源
ms.close();
}
}
// Receive
public class ReveiveDemo1 {
public static void main(String[] args) throws IOException {
MulticastSocket ms = new MulticastSocket(10000);
// 将当前本机添加到 224.0.0.1
InetAddress address = InetAddress.getByName("224.0.0.1");
ms.joinGroup(address);
// 2. 接收数据
byte[] bytes = new byte[1024];
DatagramPacket dp = new DatagramPacket(bytes, bytes.length);
ms.receive(dp);
// 3. 解析数据
byte[] data = dp.getData();
int len = dp.getLength();
String ip = dp.getAddress().getHostAddress();
String name = dp.getAddress().getHostName();
System.out.println("接收到数据: " + new String(data, 0, len));
System.out.println("该数据是从" + name + "/" + ip + "发出的");
// 4. 释放资源
ms.close();
}
}
广播
将单播程序发送的ip地址改为255.255.255.255就是广播
TCP
TCP通信程序
// Client
public class ClientDemo {
public static void main(String[] args) throws IOException {
/**
* tcp发送数据
*/
// 1. 创建Socket对象
// 创建对象的同时会连接服务端, 如果连接不是, 代码会报错
Socket socket = new Socket("127.0.0.1", 10000);
// 2. 可以从连接通道中获取输出流
OutputStream os = socket.getOutputStream();
// 写出数据
os.write("Hello TCP连接!".getBytes());
// 3. 释放资源
os.close();
socket.close();
}
}
// Server
public class ServerDemo {
public static void main(String[] args) throws IOException {
/**
* tcp接收数据
*/
// 1. 创建ServerSocket对象
ServerSocket ss = new ServerSocket(10000);
// 2. 监听客户端的连接
Socket socket = ss.accept();
// 3. 从连接通道中获取输入流读取数据
InputStream is = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
int b;
while( (b = br.read()) != -1 )
{
System.out.print((char) b);
}
// 4. 释放资源
socket.close();
ss.close();
}
}
- 中文乱码: 将字节流通过转换流转换成字符流
- 提高效率: 转成缓冲流
- 输入输出流可以无需手动关闭, 因为流是在连接通道里的, 连接断开后, 流也就关闭了
- 连接关闭时的协议:
四次挥手
, 利用四次挥手协议断开连接, 可以保证连接连接通道里的数据已经处理完毕了.
三次握手和四次挥手
- 三次握手 - 确保连接建立
- 客户端向服务器发出连接请求, 等待服务器确认
- 服务器向客户端返回一个响应, 告知客户端收到了请求
- 客户端向服务器再次发出确认信息, 连接建立
- 四次挥手 - 确保连接断开, 且数据处理完毕
- 客户端向服务器发出取消连接请求
- 服务器向客户端返回一个响应, 表示收到客户端取消请求
- 服务器将最后的数据处理完毕后, 服务器向客户端发出确认取消信息
- 客户端再次发送确认消息, 连接取消
来源
黑马程序员. 阿玮Java零基础
Gitee地址
https://gitee.com/yu-ba-ba-ba/awJava