Soket简介

Socket的英文原义是"孔"或"插座"。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原义那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。
在这里插入图片描述

测试代码

package com.pig4cloud.pig.rule.tcptest;

import cn.hutool.core.date.DateUtil;
import org.apache.http.util.TextUtils;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Date;

/**
 * @author TANGSHUAI
 * @date 2022/8/26 14:39
 */
class TcpServer {
	public static void main(String[] args) {
		//创建服务器端的Socket对象
		ServerSocket serverSocket = null;
		InputStream inputStream = null;
		try {
			serverSocket = new ServerSocket(2000);
			int i = 0;
			while (i<3) {
				//监听客户端连接,返回一个Socket对象
				Socket socket = serverSocket.accept();
				//获取输入流,读数据,并把数据显示在控制台
				inputStream = socket.getInputStream();
				byte[] bys = new byte[1024];
				int len = inputStream.read(bys);
				//String通过解码指定的字节数组使用平台的默认字符集
				String str = new String(bys, 0, len);
				//将字符串转成16进制
				String hexStr = hexStr(str);
				System.out.println("服务器返回数据:" + hexStr);
				i++;
				FileOutputStream fos = new FileOutputStream("D:\\tcpResult.txt", true);
				OutputStreamWriter sw = new OutputStreamWriter(fos);
				PrintWriter pw = new PrintWriter(sw);
				pw.println(hexStr);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//释放资源
			try {
				if (inputStream != null) {
					inputStream.close();
				}
				if (serverSocket != null) {
					serverSocket.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

	}

	/**
	 * 字符串转换成为16进制(无需Unicode编码)
	 *
	 * @param str
	 * @return
	 */
	public static String hexStr(String str) {
		char[] chars = "0123456789ABCDEF".toCharArray();
		StringBuilder sb = new StringBuilder("");
		byte[] bs = str.getBytes();
		int bit;
		for (int i = 0; i < bs.length; i++) {
			bit = (bs[i] & 0x0f0) >> 4;
			sb.append(chars[bit]);
			bit = bs[i] & 0x0f;
			sb.append(chars[bit]);
			// sb.append(' ');
		}
		return sb.toString().trim();
	}
}

public class TcpClient {
	public static void main(String[] args) {
		//1. 创建客户端套接字,并指定服务器的地址和端口号
		Socket socket = null;
		OutputStream outputStream = null;
		try {
			socket = new Socket("127.0.0.1", 2000);
			//2. 获取输出流,发送数据给服务器
			outputStream = socket.getOutputStream();
			String tcpStr = "HEX字符串数据";
			byte[] bytes = hexStrToBinaryStr(tcpStr);
			outputStream.write(bytes);
			//outputStream.flush();
			System.out.println("客户端数据发送成功!" + DateUtil.format(new Date(), "YYYY-MM-dd HH:mm:ss"));
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//4.关闭释放资源
			try {
				if (outputStream != null) {
					outputStream.close();
				}
				if (socket != null) {
					socket.close();
				}

			} catch (IOException e) {
				e.printStackTrace();
			}

		}
	}

	/**
	 * 将十六进制的字符串转换成字节数组
	 *
	 * @param hexString
	 * @return
	 */
	public static byte[] hexStrToBinaryStr(String hexString) {
		if (TextUtils.isEmpty(hexString)) {
			return null;
		}
		hexString = hexString.replaceAll(" ", "");
		int len = hexString.length();
		int index = 0;
		byte[] bytes = new byte[len / 2];
		while (index < len) {
			String sub = hexString.substring(index, index + 2);
			bytes[index / 2] = (byte) Integer.parseInt(sub, 16);
			index += 2;
		}
		return bytes;
	}


}

当SpringBoot与Socket整合,服务端监听需要异步启动,否则会出现阻塞

@Component
public class ServerSocketConfig {

	public static ServerSocket serverSocket = null;

	@Async
	public void socketCreate() {
		try {
			serverSocket = new ServerSocket(2000);
			System.out.println("socket服务端开启");
			InputStream inputStream = null;
			while (true){
				Socket socket = serverSocket.accept();
				System.out.println("接收到客户端socket" + socket);
				//获取输入流,读数据,并把数据显示在控制台
				inputStream = socket.getInputStream();
				byte[] bys = new byte[1024];
				int len = inputStream.read(bys);
				//String通过解码指定的字节数组使用平台的默认字符集
				String str = new String(bys, 0, len);
				//将字符串转成16进制
				String hexStr = hexStr(str);
				System.out.println("服务器返回数据:" + hexStr);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 字符串转换成为16进制(无需Unicode编码)
	 *
	 * @param str
	 * @return
	 */
	public static String hexStr(String str) {
		char[] chars = "0123456789ABCDEF".toCharArray();
		StringBuilder sb = new StringBuilder("");
		byte[] bs = str.getBytes();
		int bit;
		for (int i = 0; i < bs.length; i++) {
			bit = (bs[i] & 0x0f0) >> 4;
			sb.append(chars[bit]);
			bit = bs[i] & 0x0f;
			sb.append(chars[bit]);
			// sb.append(' ');
		}
		return sb.toString().trim();
	}
}

启动类加异步启动注解

@EnableAsync
@SpringBootApplication
public class RuleApplication {
    public static void main(String[] args) {
        SpringApplication.run(RuleApplication.class, args);
    }

}
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐