• socket网络编程登录实现及多客户端和服务端的数据交互


    一.TCP/IP

    客户端

    package com.demo.entity;
    
    import java.io.Serializable;
    
    public class UserInfo implements Serializable {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        /**
         * 
         */
        private String username;
        private String password;
        
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        
        
    }
    package com.demo.entity;
    
    import java.io.BufferedInputStream;
    import java.io.ObjectOutputStream;
    import java.net.Socket;
    import java.util.Scanner;
    
    public class UserClient {
        private static int port = 5566;
        private static String host = "localhost";
        
        public static void main(String[] args) {
            Socket socket =  null;
            // 创建扫描器对象
            Scanner sc = null;
            try {
                sc = new Scanner(System.in);
                // 创建一个客户端的Socket对象,获取服务端输入和输出流对象
                socket = new Socket(host, port);
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                System.out.println("请输入账号:");
                String userName = sc.nextLine();
                System.out.println("请输入密码:");
                String password = sc.nextLine();
                
                // 封装一个用户对象
                UserInfo user = new UserInfo();
                user.setPassword(password);
                user.setUsername(userName);
                
                // 序列化到输出流中
                oos.writeObject(user);
                
                // 释放流资源
                oos.flush();
                // 读取从服务端返回的数据
                BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = bis.read(buffer)) != -1) {
                    String content = new String(buffer, 0, len);
                    System.out.println("登录结果:"+content);
                }
                
                
                socket.shutdownOutput();
                socket.shutdownInput();
                
                
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (socket != null) {
                        socket.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
                sc.close();
            }
        }
    }

    服务器端

    package com.demo.entity;
    
    import java.io.Serializable;
    
    public class UserInfo implements Serializable {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        /**
         * 
         */
        private String username;
        private String password;
        
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getPassword() {
            return password;
        }
        public void setPassword(String password) {
            this.password = password;
        }
        
        
    }
    package com.demo.entity;
    
    import java.io.BufferedOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    /**
     * 1、服务器端序列化的对象全名称必须和反序列化的全名称完全一致
     * 2、序列化和反序列化对象的序列化Id必须一致
     * 3、在网络编程中需要在网络中传输对象必须实现Serializable。
     * 4、释放资源的时候流不要使用close方法关闭。
     * @author Administrator
     *
     */
    public class UserServer {
        private static int port = 5566;
    
        public static void main(String[] args) {
            ServerSocket serverSocket = null;
            Socket socket = null;
            while (true) {
                try {
                    serverSocket = new ServerSocket(port);
                    System.out.println("等待客户端连接");
                    // 服务器socket, 可以获取到客户端对应输入流和输出流对象
                    socket = serverSocket.accept();
                    System.out.println("端口号:"+socket.getPort());
                    System.out.println(socket.getInetAddress().getCanonicalHostName() + "连接到了服务器");
                    // 创建一个反序列化流
                    ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                    // 返回客户端序列化的对象
                    UserInfo user = (UserInfo) ois.readObject();
                    System.out.println(user.getPassword() + "---" + user.getUsername());
    
                    // 获取账号和密码
                    String account = user.getUsername();
                    String password = user.getPassword();
    
                    // 创建输出流
                    BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
    
                    // 判断转换和密码是否正确
                    if ("admin".equals(account) && "123".equals(password)) {
                        bos.write("登录成功".getBytes());
                    } else {
                        bos.write("登录失败".getBytes());
                    }
    
                    bos.flush();
                    bos.close();
                    ois.close();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (serverSocket != null) {
                            serverSocket.close();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    package com.demo.entity;
    
    import java.io.BufferedOutputStream;
    import java.io.IOException;
    import java.io.ObjectInputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    /**
     * 1、服务器端序列化的对象全名称必须和反序列化的全名称完全一致
     * 2、序列化和反序列化对象的序列化Id必须一致
     * 3、在网络编程中需要在网络中传输对象必须实现Serializable。
     * 4、释放资源的时候流不要使用close方法关闭。
     * @author Administrator
     *
     */
    public class UserServerM {
        private static int port = 5555;
        
        
    
        public static void main(String[] args) throws IOException {
             int clientNo = 1;
            
            ServerSocket serverSocket = new ServerSocket(port);
            // 创建一个缓存线程池
            ExecutorService pool = Executors.newCachedThreadPool();
            
            try {
                while (true) {
                    Socket socket = serverSocket.accept();
                    pool.execute(new SingleServer(clientNo++, socket));
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                pool.shutdown();
                if (!serverSocket.isClosed()) {
                    serverSocket.close();
                }
            }
            
            
        }
    }
    
    class SingleServer  implements Runnable {
        
        private int clientNo; // 客户端编号
        private Socket socket;
        
        public SingleServer(int clientNo, Socket socket) {
            this.clientNo = clientNo;
            this.socket = socket;
        }
    
        @Override
        public void run() {
            System.out.println("第"+clientNo+"客户端连接到了服务器");
            System.out.println("port:"+socket.getPort());
            System.out.println(socket.getInetAddress().getCanonicalHostName() + "连接到了服务器");
            try {
                // 创建一个反序列化流
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                // 返回客户端序列化的对象
                UserInfo user = (UserInfo) ois.readObject();
                System.out.println(user.getPassword() + "---" + user.getUsername());
    
                // 获取账号和密码
                String account = user.getUsername();
                String password = user.getPassword();
    
                // 创建输出流
                BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
    
                // 判断转换和密码是否正确
                if ("admin".equals(account) && "123".equals(password)) {
                    bos.write("登录成功".getBytes());
                } else {
                    bos.write("登录失败".getBytes());
                }
    
                bos.flush();
                bos.close();
                ois.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (!socket.isConnected()) {
                        socket.close();
                    }
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
        
    }

     二.UDP

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
     
    /*
     * 客户端
     */
    public class UDPClient {
        public static void main(String[] args) throws IOException {
            /*
             * 向服务器端发送数据
             */
            // 1.定义服务器的地址、端口号、数据
            InetAddress address = InetAddress.getByName("localhost");
            int port = 8800;
            byte[] data = "用户名:admin;密码:123".getBytes();
            // 2.创建数据报,包含发送的数据信息
            DatagramPacket packet = new DatagramPacket(data, data.length, address, port);
            // 3.创建DatagramSocket对象
            DatagramSocket socket = new DatagramSocket();
            // 4.向服务器端发送数据报
            socket.send(packet);
     
            /*
             * 接收服务器端响应的数据
             */
            // 1.创建数据报,用于接收服务器端响应的数据
            byte[] data2 = new byte[1024];
            DatagramPacket packet2 = new DatagramPacket(data2, data2.length);
            // 2.接收服务器响应的数据
            socket.receive(packet2);
            // 3.读取数据
            String reply = new String(data2, 0, packet2.getLength());
            System.out.println("我是客户端,服务器说:" + reply);
            // 4.关闭资源
            socket.close();
        }
    }
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
     
    /*
     * 服务器端,实现基于UDP的用户登陆
     */
    public class UDPServer {
        public static void main(String[] args) throws IOException {
            /*
             * 接收客户端发送的数据
             */
            // 1.创建服务器端DatagramSocket,指定端口
            DatagramSocket socket = new DatagramSocket(8800);
            // 2.创建数据报,用于接收客户端发送的数据
            byte[] data = new byte[1024];// 创建字节数组,指定接收的数据包的大小
            DatagramPacket packet = new DatagramPacket(data, data.length);
            // 3.接收客户端发送的数据
            System.out.println("****服务器端已经启动,等待客户端发送数据");
            socket.receive(packet);// 此方法在接收到数据报之前会一直阻塞
            // 4.读取数据
            String info = new String(data, 0, packet.getLength());
            System.out.println("我是服务器,客户端说:" + info);
     
            /*
             * 向客户端响应数据
             */
            // 1.定义客户端的地址、端口号、数据
            InetAddress address = packet.getAddress();
            int port = packet.getPort();
            byte[] data2 = "欢迎您!".getBytes();
            // 2.创建数据报,包含响应的数据信息
            DatagramPacket packet2 = new DatagramPacket(data2, data2.length, address, port);
            // 3.响应客户端
            socket.send(packet2);
            // 4.关闭资源
            socket.close();
        }
    }
  • 相关阅读:
    java.lang.NoClassDefFoundError: TagSupport 错误
    ${pageContext.request.contextPath}的作用
    JS获取table表格任意单元格值
    数据库导出为Excel
    requestScope含义
    每种创伤,都是另一种成熟
    关于AJAX
    the public type xxx must be defined in its own file
    MyEclipse取消Show in Breadcrumb的方法
    Sql2005里获取表的结构SQL
  • 原文地址:https://www.cnblogs.com/sunBinary/p/10604536.html
Copyright © 2020-2023  润新知