启动自定义代码的方式
WebServer Initialized Event
java
//@Component
//ApplicationContext context 注入
//@PostConstruct
//@Async
@EventListener(ApplicationReadyEvent.class)
@Component
public class TcpServerListener implements ApplicationListener<WebServerInitializedEvent> {
@Override
public void onApplicationEvent(WebServerInitializedEvent event) {
//int serverPort = event.getWebServer().getPort();
// 在此处添加代码以创建和启动 TCP 服务器
updateServer.startServer(8082);
}
}
ServerSocket
基本代码
java
// 创建ServerSocket并绑定端口
ServerSocket serverSocket = new ServerSocket(8080);
// 启动一个新线程来接受客户端连接
while (true) {
try {
// 接受客户端连接
Socket clientSocket = serverSocket.accept();
// 关闭客户端连接
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
DataInputStream
java
@PostConstruct
@Async
public void startServer() throws Exception {
//开启TCP Server
ServerSocket serverSocket = new ServerSocket(8082);
log.info("服务端打开了 Server started on port {}", 8082);
while (true) {
//等待连接
Socket socket = serverSocket.accept();
//获取 输入流
DataInputStream inputStream = new DataInputStream(socket.getInputStream());
DataOutputStream outputStream = new DataOutputStream(socket.getOutputStream());
log.info("服务端收到了连接:Accepted connection from client: {}", socket.getInetAddress());
//读取的字节数
byte[] buffer = new byte[380];//1024
//真正读取到了多少个
int bytesRead;
//循环进行读取
while ((bytesRead = inputStream.read(buffer)) != -1) {
//处理二进制数据
processBinaryData(buffer, bytesRead, socket, outputStream);
}//循环读取,正常每次都会读取完毕
inputStream.close();
outputStream.close();
socket.close();
}//死循环接收连接
}//初始化方法结束*/
//关闭输入流
//socket.shutdownInput();
//关闭输出流,关闭 Socket
//socket.shutdownOutput();
//关闭Socket
//socket.close();
InputStreamReader 字符流
- BufferedReader(new InputStreamReader(socket.getInputStream()))
- new PrintWriter(socket.getOutputStream(), true)
java
public class TcpServer {
public static void main(String[] args) {
try {
//连接
ServerSocket serverSocket = new ServerSocket(5555);
System.out.println("服务器启动,等待客户端连接...");
//阻塞
Socket socket = serverSocket.accept();
System.out.println("客户端已连接.");
//创建 输入流。读取
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
//创建 输出流。写入
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
String message = in.readLine();
System.out.println("收到客户端消息:" + message);
// 解析 JSON 消息
// 发送响应给客户端
out.println("构建响应 JSON");
// 关闭连接
socket.close();
serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
NIO Selector
ServerSocketChannel
java
@Configuration
public class TcpServerConfig {
//@Value("${tcp.ip}")
//private String tcpIp;
//ApplicationContext context
//@PostConstruct
//@Async
@EventListener(ApplicationReadyEvent.class)
public void startServer() {// throws IOException
//异步执行
//ThreadUtil.execAsync(() -> {
try {
//1.打开选择器
Selector selector = Selector.open();
//2.打开通道 serverSocketChannel
ServerSocketChannel channel = ServerSocketChannel.open();
//3.设置非阻塞
channel.configureBlocking(false);
//4.绑定本机IP
channel.bind(new InetSocketAddress(tcpIp, 8082));
//5.进行注册
channel.register(selector, SelectionKey.OP_ACCEPT);
log.info("===============Server started on port 8082===================");
while (true) {
//6.选择通道
int readyChannels = selector.select();
//校验下
if (readyChannels == 0) {
continue;
}
//7.获取所有的key
Set<SelectionKey> selectedKeys = selector.selectedKeys();
//8.获取迭代器
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
//如果存在
while (keyIterator.hasNext()) {
//9.获取这个key
SelectionKey key = keyIterator.next();
//10.如果是个连接
if (key.isAcceptable()) {
//11.接收这个通道
SocketChannel clientSocketChannel = serverSocketChannel.accept();
//12.非阻塞的
clientSocketChannel.configureBlocking(false);
//13.注册为可读
clientSocketChannel.register(selector, SelectionKey.OP_READ);
log.info("收到连接:Accepted connection from: {}", clientSocketChannel.getRemoteAddress());
} else if (key.isReadable()) {
//14.如果是可读,获取通道
SocketChannel clientSocketChannel = (SocketChannel) key.channel();
//读取数量
ByteBuffer buffer = ByteBuffer.allocate(38);//1024
//15.真实读取到了多少个
int bytesRead = -1;
try {
//这里报错了,增加防护,如果没防护,这个nio就断了
bytesRead = clientSocketChannel.read(buffer);
} catch (Exception e) {
log.info("未读取到");
e.printStackTrace();
}
//未读取到 关闭
if (bytesRead == -1) {
clientSocketChannel.close();
} else if (bytesRead > 0) { //读到的 > 0
//读取到了
buffer.flip();
//读到这个字节里
byte[] data = new byte[bytesRead];
buffer.get(data);
//处理逻辑
processBinaryData(data, bytesRead, clientSocketChannel);
//String message = new String(data).trim();
//System.out.println("Received message: " + message);
//清理
buffer.clear();
}//读到了
}//是可读的
//移除key
keyIterator.remove();
}//如果存在
}//死循环
} catch (Exception e) {
e.printStackTrace();
}
//}, "MyTcpServerThread").start();
}
java
//有错误,往外层抛
private void sendUpdateMessage(SocketChannel clientSocketChannel) {
//转为byte
byte[] binaryData = hexStringToBytes("dfsfsdfdsaf");
//1.申请字节
ByteBuffer buffer = ByteBuffer.allocate(binaryData.length);
//2.放入
buffer.put(binaryData);
//3. 快速翻阅,浏览
buffer.flip();
//3.循环是否有:剩下的,遗留的;尚未使用、解决的
while (buffer.hasRemaining()) {
try {
//进行写入
clientSocketChannel.write(buffer);
log.info("发送了一次升级的消息");
} catch (IOException e) {
log.info("发送升级失败");
e.printStackTrace();
}
}
}