zoukankan      html  css  js  c++  java
  • 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;
        }
    }
  • 相关阅读:
    什么是主从复制、读写分离、为什么要使用
    Swift 4.0 + Ipad开发项目中值得注意知识点
    Swift细节记录<一>
    ECMAScript 6复习<一>
    Swift4.0复习访问控制与作用域
    Swift4.0复习操作符方法与操作符的定制
    Swift4.0复习错误处理
    Swift4.0复习扩展
    Swift4.0复习泛型
    TCP的三次握手(建立连接)和四次挥手(关闭连接)
  • 原文地址:https://www.cnblogs.com/zhouheblog/p/10688511.html
Copyright © 2011-2022 走看看