Java 中的网络支持:
- InetAddress:用于表示网络上的硬件资源,即 IP 地址;
- URL:统一资源定位符;
- Sockets:使用 TCP 协议实现网络通信;
- Datagram:使用 UDP 协议实现网络通信。
InetAddress
没有公有的构造函数,只能通过静态方法来创建实例。
InetAddress.getByName(String host);
InetAddress.getByAddress(byte[] address);
public class NetDemo {
public static void main(String[] args) throws UnknownHostException {
// public static InetAddress getByName(String host)
InetAddress address = InetAddress.getByName("LAPTOP-D9966H06");
//InetAddress address = InetAddress.getByName("223.3.108.211");
//InetAddress address = InetAddress.getByName("192.168.2.1");
// 获取两个东西:主机名,IP地址
// public String getHostName()
String name = address.getHostName();
// public String getHostAddress()
String ip = address.getHostAddress();
System.out.println(name + "---" + ip);
}
}
URL
可以直接从 URL 中读取字节流数据。
public static void main(String[] args) throws IOException {
URL url = new URL("http://www.baidu.com");
/* 字节流 */
InputStream is = url.openStream();
/* 字符流 */
InputStreamReader isr = new InputStreamReader(is, "utf-8");
/* 提供缓存功能 */
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
br.close();
}
Sockets
- ServerSocket:服务器端类
- Socket:客户端类
- 服务器和客户端通过 InputStream 和 OutputStream 进行输入输出。
Datagram
- DatagramSocket:通信类
- DatagramPacket:数据包类
UDP协议
通信规则
- 将数据源和目的封装成数据包中,不需要建立连接;
- 每个数据报的大小在限制在64k;
- 因无连接,是不可靠协议;
- 不需要建立连接,速度快
UDP协议发送数据
- 创建发送端Socket对象
- 创建数据,并把数据打包
- 调用Socket对象的发送方法发送数据包
- 释放资源
public class SendDemo {
public static void main(String[] args) throws IOException {
//1. 创建发送端Socket对象
DatagramSocket ds=new DatagramSocket();
//2. 创建数据,并把数据打包
byte[] bys="hello".getBytes();
// 长度
int length = bys.length;
// IP地址对象
InetAddress address = InetAddress.getByName("LAPTOP-D9966H06");
// 端口
int port = 10086;
DatagramPacket dp = new DatagramPacket(bys, length, address, port);
//3. 调用Socket对象的发送方法发送数据包
ds.send(dp);
//4. 释放资源
ds.close();
}
}
UDP协议接收数据
- 创建接收端Socket对象
- 创建一个数据包(接收容器)
- 调用Socket对象的接收方法接收数据
- 解析数据包,并显示在控制台
- 释放资源
public class ReceiveDemo {
public static void main(String[] args) throws IOException {
//1. 创建接收端Socket对象
DatagramSocket ds=new DatagramSocket(10086);
//2. 创建一个数据包(接收容器)
byte[] bys=new byte[1024];
int length=bys.length;
DatagramPacket dp=new DatagramPacket(bys,length);
//3. 调用Socket对象的接收方法接收数据
//public void receive(DatagramPacket p)
ds.receive(dp);//阻塞式
//4. 解析数据包,并显示在控制台
InetAddress inetAddress=dp.getAddress();
String ip=inetAddress.getHostAddress();
// public byte[] getData():获取数据缓冲区
// public int getLength():获取数据的实际长度
byte[] bys2 = dp.getData();
int len = dp.getLength();
String s = new String(bys2, 0, len);
System.out.println(ip + "传递的数据是:" + s);
//5. 释放资源
ds.close();
}
}
使用UDP传输键盘录入的数据
- 接收端:
public class ReceiveDemo2 {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket(12345);
while (true){
byte[] bys=new byte[1024];
DatagramPacket dp=new DatagramPacket(bys,bys.length);
ds.receive(dp);
//阻塞式
String ip=dp.getAddress().getHostAddress();
String s = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + "传递的数据是:" + s);
}
//接收端应该一直开着等待接收数据,不需要释放资源
//ds.close();
}
}
- 发送端:
public class SendDemo2 {
public static void main(String[] args) throws IOException {
DatagramSocket ds=new DatagramSocket();
//封装键盘录入数据
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String line=null;
while(true){
line=br.readLine();
if("-1".equals(line)){
break;
}
byte[] bys=line.getBytes();
DatagramPacket dp=
new DatagramPacket(bys,bys.length,InetAddress.getByName("LAPTOP-D9966H06"),12345);
ds.send(dp);
}
br.close();
//4. 释放资源
ds.close();
}
}
TCP协议
通信规则
- 建立连接,形成传输数据的通道;
- 在连接中进行大数据量传输;
- 通过三次握手完成连接,是可靠协议;
4.必须建立连接,效率会稍低
TCP协议发送数据
- 创建发送端的Socket对象:这一步如果成功,就说明连接已经建立成功了。
- 获取输出流,写数据
- 释放资源
public class ClientDemo {
public static void main(String[] args) throws IOException {
//1. 创建发送端的Socket对象:这一步如果成功,就说明连接已经建立成功了。
Socket socket=new Socket("LAPTOP-D9966H06",8888);
//2. 获取输出流,写数据
OutputStream outputStream=socket.getOutputStream();
outputStream.write("hello".getBytes());
//3. 释放资源
socket.close();
}
}
TCP协议接收数据
- 创建接收端的Socket对象
- 监听客户端连接。返回一个对应的Socket对象
- 获取输入流,读取数据显示在控制台
- 释放资源
public class ServerDemo {
public static void main(String[] args) throws IOException {
//1. 创建接收端的Socket对象
ServerSocket serverSocket=new ServerSocket(8888);
//2. 监听客户端连接。返回一个对应的Socket对象
Socket socket=serverSocket.accept();
//3. 获取输入流,读取数据显示在控制台
InputStream inputStream=socket.getInputStream();
byte[] bys = new byte[1024];
int len = inputStream.read(bys);
// 阻塞式方法
String str = new String(bys, 0, len);
String ip = socket.getInetAddress().getHostAddress();
System.out.println(ip + "---" + str);
//4. 释放资源
socket.close();
}
}
- 注意:TCP通信中服务端也可以向客户端发送数据
public class ServerDemo2 {
public static void main(String[] args) throws IOException {
//1. 创建接收端的Socket对象
ServerSocket serverSocket=new ServerSocket(8888);
//2. 监听客户端连接。返回一个对应的Socket对象
Socket socket=serverSocket.accept();
//3. 获取输入流,读取数据显示在控制台
InputStream inputStream=socket.getInputStream();
byte[] bys = new byte[1024];
int len = inputStream.read(bys);
String str = new String(bys, 0, len);
String ip = socket.getInetAddress().getHostAddress();
System.out.println(ip + "---" + str);
//向客户端发送数据
OutputStream outputStream=socket.getOutputStream();
outputStream.write("数据已经收到".getBytes());
//4. 释放资源
socket.close();
}
}
public class ClientDemo2 {
public static void main(String[] args) throws IOException {
//1. 创建发送端的Socket对象:这一步如果成功,就说明连接已经建立成功了。
Socket socket=new Socket("LAPTOP-D9966H06",8888);
//2. 获取输出流,写数据
OutputStream outputStream=socket.getOutputStream();
outputStream.write("hello".getBytes());
//从服务端获取反馈信息
InputStream inputStream=socket.getInputStream();
byte[] bys=new byte[1024];
int len=inputStream.read(bys);
String reback=new String(bys,0,len);
System.out.println("reback:"+reback);
//3. 释放资源
socket.close();
}
}
客户端键盘录入,服务器输出到控制台
- 服务端:
public class ServerDemo3 {
public static void main(String[] args) throws IOException {
//1. 创建接收端的Socket对象
ServerSocket serverSocket=new ServerSocket(8888);
//2. 监听客户端连接。返回一个对应的Socket对象
Socket socket=serverSocket.accept();
//3. 获取输入流,读取数据显示在控制台
//这里对输入流要进行包装
InputStream inputStream=socket.getInputStream();
BufferedReader br=new BufferedReader(new InputStreamReader(inputStream));
String line=null;
while((line=br.readLine())!=null){
System.out.println(line);
}
//4. 释放资源
socket.close();
}
}
- 客户端:
public class ClientDemo3 {
public static void main(String[] args) throws IOException {
//1. 创建发送端的Socket对象:这一步如果成功,就说明连接已经建立成功了。
Socket socket=new Socket("LAPTOP-D9966H06",8888);
//键盘录入数据
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
//2. 获取输出流,写数据
//对输出流进行包装
OutputStream outputStream=socket.getOutputStream();
BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(outputStream));
String line=null;
while(true){
line=br.readLine();
if("-1".equals(line)){
break;
}
bw.write(line);
bw.newLine();
bw.flush();
}
//3. 释放资源
socket.close();
}
}