java Socket实例
可以实现客户端与服务端双向通信,支持多客户端连接,客户端断开连接,服务端不会出现异常
服务端代码:
package com.thinkgem.jeesite.modules.socketTest.demo1; import java.io.BufferedInputStream; import java.io.DataInputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; /** * @Author: zhouhe * @Date: 2019/4/10 16:56 */ public class Server { private static class ClientHandler implements Runnable { private Socket socket; public ClientHandler(Socket socket) { this.socket = socket; } @Override public void run() { try { //封装输入流(接收客户端的流) BufferedInputStream bis = new BufferedInputStream( socket.getInputStream()); DataInputStream dis = new DataInputStream(bis); byte[] bytes = new byte[1]; // 一次读取一个byte System.out.println("bytes:"+bytesToHexString(bytes)); String ret = ""; while (dis.read(bytes) != -1) { ret += bytesToHexString(bytes) + ""; if (dis.available() == 0) { //一个请求 System.out.println(socket.getRemoteSocketAddress() + ":" + ret); System.out.println("转换为字符串后:"+hexStringToString(ret)); ret = ""; } } } catch (Exception e) { e.printStackTrace(); } finally { System.out.println("client is over"); if (socket != null) { try { socket.close(); } catch (IOException e) { e.printStackTrace(); } } } } } /** * byte[]数组转换为16进制的字符串 * * @param bytes 要转换的字节数组 * @return 转换后的结果 */ public static String bytesToHexString(byte[] bytes) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < bytes.length; i++) { String hex = Integer.toHexString(0xFF & bytes[i]); if (hex.length() == 1) { sb.append('0'); } sb.append(hex); } return sb.toString(); } /** * 16进制转换成为string类型字符串 * 这个方法中文会乱码,字母和数字都不会乱码 * * @Author zhouhe * @param s * @return */ public static String hexStringToString(String s) { if (s == null || s.equals("")) { return null; } s = s.replace(" ", ""); byte[] baKeyword = new byte[s.length() / 2]; for (int i = 0; i < baKeyword.length; i++) { try { baKeyword[i] = (byte) (0xff & Integer.parseInt(s.substring(i * 2, i * 2 + 2), 16)); } catch (Exception e) { e.printStackTrace(); } } try { s = new String(baKeyword, "UTF-8"); new String(); } catch (Exception e1) { e1.printStackTrace(); } return s; } //测试方法 public static void main(String[] args) { ServerSocket server = null; try { server = new ServerSocket(10010); while (true) { System.out.println("listening..."); Socket socket = server.accept(); System.out.println("连接客户端地址:" + socket.getRemoteSocketAddress()); System.out.println("connected..."); ClientHandler handler = new ClientHandler(socket); Thread t = new Thread(handler); t.start(); } } catch (Exception e) { e.printStackTrace(); } finally { if (server != null) { try { server.close(); } catch (IOException e) { e.printStackTrace(); } } } } }
客户端代码:
package com.thinkgem.jeesite.modules.socketTest.demo1; import java.io.OutputStream; import java.math.BigInteger; import java.net.Socket; import java.util.Scanner; /** * @Author: zhouhe * @Date: 2019/4/10 16:55 */ public class Client { public static void main(String[] args) { //TODO 16进制 转换为10进制 //String str = new BigInteger("01 10 00 00 00 02 04 00 01 00 00 a2 6f", 16).toString(10); //System.out.println(str); Socket socket = null; try { System.out.println("connecting..."); socket = new Socket("127.0.0.1", 12888); System.out.println("connection success"); // 输入任意字符发送,输入q退出 Scanner in = new Scanner(System.in); String str = "01 10 00 00 00 02 04 00 01 00 00 a2 6f"; //发送的16进制字符串 byte[] bytes = hexStringToByteArray(str); OutputStream os = socket.getOutputStream(); while (!(in.nextLine()).equals("q")) { //输入q退出 os.write(bytes); } os.close(); } catch (Exception e) { e.printStackTrace(); } finally { if (socket != null) { try { socket.close(); } catch (Exception e) { } } } } /** * 16进制表示的字符串转换为字节数组 * * @param hexString 16进制表示的字符串 * @return byte[] 字节数组 */ public static byte[] hexStringToByteArray(String hexString) { hexString = hexString.replaceAll(" ", ""); int len = hexString.length(); byte[] bytes = new byte[len / 2]; for (int i = 0; i < len; i += 2) { // 两位一组,表示一个字节,把这样表示的16进制字符串,还原成一个字节 bytes[i / 2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character .digit(hexString.charAt(i + 1), 16)); } return bytes; } }