java中的网络支持 [技术实现]
1.InetAddress:用于标识网络上的硬件资源
2.URL:统一资源定位符 通过URL可以直接读取或写入网络上的数据
3.Sockets 使用TCP协议实现网络通信的Socket相关的类
4Datagram:使用UDP协议,将数据保存在数据报中,通过网络进行通信
InetAddress类
InetAddress类用于标识网络上的硬件资源表示互联网协议IP地址
没有构造方法,通过调用static方法获取实例
1.getLocalHost返回本地主机。
public static InetAddress getLocalHost() throws UnknownHostException
返回:本地主机的 IP 地址。
抛出:UnknownHostException - 如果找不到 host 的任何 IP 地址。
使用:
//获取实例
InetAddress address = InetAddress.getLoacalHost();
address.getHostName();//获取主机名
address.getHostAddress();//获取本机ip
InetAddress address = InetAddress.get..By...();//其他获取实例的方法
2.根据计算机名/ip获取实例
InetAddress.getByName("主机名");
InetAddress.getByName("IP地址");
java.net.URL类
统一资源定位符 协议:资源名称
try{
URL myURL = new URL("https://blog.csdn.net");
//也可以加?的参数 和#的锚点
URL myURL2 = new URL(myURL ,"/qq_36762677");
myURL2.getProtocol();//获取协议名
myURL2.getPort();//获取端口号,默认端口号返回-1
myURL2.getHost();//获取主机
}catch(Exception e){
}
使用URL读取页面内容[ java爬虫 ]
try{
URL url = new URL("https://blog.csdn.net/qq_36762677");
// 获取字节输入流
InputStream is = url.openStream();
// 将字节输入流转为字符输入流
InputStreamReader isr = new InputStreamReader(is,"utf-8");
//为字符输入流添加缓冲,提高读取效率
BufferedReader br = new BufferedReader(isr);
String data = br.readLine();//读取数据
while(data!=null){
System.out.println(data);
data = br.readLine();
}
br.close();
isr.close();
is.close();
}
socket编程
服务端java.net.ServerSocket 客户端Socket
服务端代码
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
/**
* @author zhaojy
* @date 19/12/15 11:03
*/
public class SocketServer {
/**
* 当前连接数
*/
public static int count = 0;
public static void main(String[] args) throws Exception {
// 开始监听8888 port
try (ServerSocket serverSocket = new ServerSocket(8888)) {
// 循环接收客户端请求
while (true) {
Socket socket = serverSocket.accept();
ServerThread serverThread = new ServerThread(socket);
count++;
// 设置线程优先级[1-10] 默认5,防止运行速度减慢
serverThread.setPriority();
serverThread.start();
InetAddress clientInetAddress = socket.getInetAddress();
System.out.println("当前连接数:" + count + "客户端IP" + clientInetAddress.getHostAddress());
}
} catch (Exception e) {
e.printStackTrace();
}
}
static class ServerThread extends Thread {
Socket socket = null;
public ServerThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
//字节输入流
try (InputStream is = socket.getInputStream()) {
//提高性能,变字符流
try (InputStreamReader isr = new InputStreamReader(is)) {
//为字符输入流添加缓冲
try (BufferedReader br = new BufferedReader(isr)) {
//读取数据
String data = br.readLine();
while (data != null) {
System.out.println("收到客户端发来的消息:"+data);
data = br.readLine();
}
try (OutputStream os = socket.getOutputStream()) {
try (PrintWriter pw = new PrintWriter(os)) {
pw.write("听得到");
pw.flush();
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
try {
SocketServer.count--;
System.out.println("连接断开----剩余连接数" + count);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
客户端代码
import java.io.*;
import java.net.Socket;
/**
* @author zhaojy
* @date 19/12/15 11:03
*/
public class SocketClient {
public static void main(String[] args) throws Exception {
try( Socket socket = new Socket("127.0.0.1",8888)){
// 获取输出流, 向服务器发送消息
OutputStream os = socket.getOutputStream();
// 将输出流包装成打印流
PrintWriter pw = new PrintWriter(os);
pw.print("能听到吗");
pw.flush();
socket.shutdownOutput();
//字节输入流
InputStream is = socket.getInputStream();
//提高性能,变字符流
InputStreamReader isr = new InputStreamReader(is);
//为字符输入流添加缓冲
BufferedReader br = new BufferedReader(isr);
//读取数据
String data = br.readLine();
while (data != null) {
System.out.println(data);
data = br.readLine();
}
br.close();
isr.close();
is.close();
pw.close();
os.close();
}catch (Exception e){
}
}
}
2. 基于UDP的Socket编程
服务端代码:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @author zhaojy
* @date 19/12/15 11:03
*/
public class SocketServer {
public static void main(String[] args) throws Exception {
// 创建服务端
DatagramSocket datagramSocket = new DatagramSocket(8889);
// 创建数据报
DatagramPacket datagramPacket = getDatagramPacket(datagramSocket);
// 接收后获取客户端地址,端口 进行响应
InetAddress address = datagramPacket.getAddress();
int port = datagramPacket.getPort();
byte[] byte1 = "收到".getBytes();
DatagramPacket packet2 = new DatagramPacket(byte1, byte1.length, address, port);
datagramSocket.send(packet2);
datagramSocket.close();
}
private static DatagramPacket getDatagramPacket(DatagramSocket datagramSocket) throws IOException {
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
// 接收数据, 再没接收到会一直阻塞
datagramSocket.receive(datagramPacket);
// 读取数据
String info = new String(bytes, 0, datagramPacket.getLength());
System.out.println("服务端收到消息:" + info);
return datagramPacket;
}
}
客户端代码:
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
/**
* @author zhaojy
* @date 19/12/15 11:03
*/
public class SocketClient {
public static void main(String[] args) throws Exception {
// 定义服务端 地址,端口
InetAddress address = InetAddress.getByName("localhost");
int port = 8889;
// 定义发送的数据报
byte[] data = "你好?".getBytes();
DatagramPacket datagramPacket = new DatagramPacket(data, data.length, address, port);
DatagramSocket socket = new DatagramSocket();
socket.send(datagramPacket);
DatagramPacket serverPacket = getDatagramPacket(socket);
}
private static DatagramPacket getDatagramPacket(DatagramSocket datagramSocket) throws IOException {
byte[] bytes = new byte[1024];
DatagramPacket datagramPacket = new DatagramPacket(bytes, bytes.length);
// 接收数据, 再没接收到会一直阻塞
datagramSocket.receive(datagramPacket);
// 读取数据
String info = new String(bytes, 0, datagramPacket.getLength());
System.out.println("客户端收到消息:" + info);
return datagramPacket;
}
}
传输文件和对象
http://www.imooc.com/article/16226
STOMP 简单文本协议
(WebSocket遵循此规范)
,类似http,基于TCP
支持STOMP的产品:RabbitMQ等
learn more
WebSocket
基于TCP的一种的网络协议,实现了浏览器与服务器全双工通信,允许服务器发送信息给客户端
解决了客户端与服务端实时通信而产生的技术,http只能客户端发起
HTTP协议是半双工协议,也就是说在同一时间点只能处理一个方向的数据传输,同时HTTP消息也是过于庞大,里面包含大量消息头数据,真正在消息处理中很多数据不是必须的,这也是对资源的浪费。
使用场景
两种通讯模式
ws生命周期
打开事件
消息事件 文本,二进制
错误事件
关闭事件
SockJS
是一个浏览器JavaScript库,它提供了一个类似于网络的对象。SockJS提供了一个连贯的、跨浏览器的Javascript API,它在浏览器和web服务器之间创建了一个低延迟、全双工、跨域通信通道。
服务端注解
@``ServerEndpoint(value = "/webSocketProxy/{nickName}")
表示一个URI映射的路径,标准的restfulAPI,{nickName}为路径参数。用于注解于类上。
@OnOpen @OnMessage @OnClose @OnError
以上四个注解用于方法上,分别对应不同的事件:打开连接、收到消息、连接关闭、发生错误。当发生对应事件时,该方法将会被触发。通常开发中主要在@OnMessage方法内进行业务开发。
@PathParam("nickName")
此注解用于获取路径参数{nickName}。
当WS使用Nginx反向代理时,需要在Nginx Conf上添加配置
链接状态
NOT_YET_CONNECTED, CONNECTING, OPEN, CLOSING, CLOSED;
spring-websocket 开源代码
https://github.com/ai1045152332/SpringBoot-Cloud/tree/master/springboot-websocket