• 网络编程。。


    Socket简介

    什么是Socket?

    1. Socket的底层机制复杂,Java平台提供了一些简单的API,可以更简单有效的使用Socket开发而无需了解底层机制

    2. 通信链路的端点就被称为“套接字”(英文名Socket)是提供给应用程序的接口

    基于TCP协议的Socket编程

    基于TCP协议的Socket网络通信

    用来实现双向安全连接网络通信

    Socket通信模型

    进行网络通信时,Socket需要借助数据流来完成数据的传递工作

     

    Socket网络编程一般可以分成如下步骤进行

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    ​
    public class Client {
    ​
        public static void main(String[] args) {
            Socket socket = null;
            OutputStream os = null;
            InputStream is = null;
            BufferedReader br = null;
            try {
                //创建通信链路的端点客户端套接字
                socket = new Socket("127.0.0.1", 8888);
                //获取输出流将数据发送出去
                os = socket.getOutputStream();
                String str = "用户名:zhangsan 密码:123456";
                os.write(str.getBytes());
                System.out.println("我是客户端,我将数据发送完毕");
                //关闭通道
                socket.shutdownOutput();
                //客户端需要通过输入流读取服务器端发送过来的消息
                is = socket.getInputStream();
                br = new BufferedReader(new InputStreamReader(is));
                String result = br.readLine();
                System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{           
                try {               
                    br.close();
                    is.close();
                    os.close();
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    ​
            }
        }
    }
    ​
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    ​
    public class Server {
    ​
        public static void main(String[] args) {
            ServerSocket ss= null;
            Socket socket = null;
            InputStream is = null;
            BufferedReader br = null;
            OutputStream os = null;
            try {
                //创建服务器端套接字ServerSocket
                ss= new ServerSocket(8888);
                //服务器通过调用侦听方法来获取客户端的请求
                socket = ss.accept();
                //通过返回的Socket对象调用方法获取一个输入流来读取客户端发送过来的消息
                is = socket.getInputStream();
                //通过输入流读取客户端发送的消息
                br = new BufferedReader(new InputStreamReader(is));
                String str = br.readLine();
                System.out.println("我这边是服务器:客户端发送给我的数据是:"+str);
                //关闭通道
                socket.shutdownInput();
                //服务器接收客户端消息后,需要给客户端一个响应信息
                os = socket.getOutputStream();
                String result = "用户名和密码正确,可以登录";
                os.write(result.getBytes());
                System.out.println("给客户端的响应信息发送成功");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                
                try {
                    os.close();
                    br.close();
                    is.close();
                    socket.close();
                    ss.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }                   
            }   
        }
    }

    Socket中实现对象的传递

    传递对象信息

     

    import java.io.IOException;
    import java.io.InputStream;
    import java.io.ObjectInputStream;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    ​
    public class Server {
    ​
        public static void main(String[] args) {
            ServerSocket ss= null;
            Socket socket = null;
            InputStream is = null;
            ObjectInputStream ois =null;
            OutputStream os = null;
            try {
                //创建服务器端套接字ServerSocket
                ss= new ServerSocket(8888);
                //服务器通过调用侦听方法来获取客户端的请求
                socket = ss.accept();
                //通过返回的Socket对象调用方法获取一个输入流来读取客户端发送过来的消息
                is = socket.getInputStream();
                //通过输入流读取客户端发送的消息
                ois = new ObjectInputStream(is);
                Student student = (Student)ois.readObject();
                System.out.println("我这边是服务器:客户端发送给我的数据是:"+student);
                //关闭通道
                socket.shutdownInput();
                //服务器接收客户端消息后,需要给客户端一个响应信息
                os = socket.getOutputStream();
                String result = "获取的对象姓名和年龄正确";
                os.write(result.getBytes());
                System.out.println("给客户端的响应信息发送成功");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                
                try {
                    os.close();
                    ois.close();
                    is.close();
                    socket.close();
                    ss.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                
                
            }
            
            
        }
    }
    ​
    import java.io.Serializable;
    ​
    public class Student implements Serializable {
        private String name;
        private int age;
    ​
        public Student() {
            super();
        }
    ​
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    ​
        public String getName() {
            return name;
        }
    ​
        public void setName(String name) {
            this.name = name;
        }
    ​
        public int getAge() {
            return age;
        }
    ​
        public void setAge(int age) {
            this.age = age;
        }
    ​
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + "]";
        }
    ​
    }
    ​
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    ​
    public class Client {
    ​
        public static void main(String[] args) {
            Socket socket = null;
            OutputStream os = null;
            ObjectOutputStream oos = null;
            InputStream is = null;
            BufferedReader br = null;
            try {
                //创建通信链路的端点客户端套接字
                socket = new Socket("127.0.0.1", 8888);
                //获取输出流将数据发送出去
                os = socket.getOutputStream();
                Student student = new Student("张三", 23);
                oos = new ObjectOutputStream(os);
                oos.writeObject(student);
                System.out.println("我是客户端,我将数据发送完毕");
                //关闭通道
                socket.shutdownOutput();
                //客户端需要通过输入流读取服务器端发送过来的消息
                is = socket.getInputStream();
                br = new BufferedReader(new InputStreamReader(is));
                String result = br.readLine();
                System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{           
                try {               
                    br.close();
                    is.close();
                    oos.close();
                    os.close();
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    ​
            }
        }
    }
    ​

    多线程处理多请求

     

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    ​
    import cn.bdqn.demo03.Student;
    ​
    public class Client1 {
        public static void main(String[] args) {
            Socket socket = null;
            OutputStream os = null;
            ObjectOutputStream oos = null;
            InputStream is = null;
            BufferedReader br = null;
            try {
                //创建通信链路的端点客户端套接字
                socket = new Socket("127.0.0.1", 8888);
                //获取输出流将数据发送出去
                os = socket.getOutputStream();
                Student student = new Student("张三", 23);
                oos = new ObjectOutputStream(os);
                oos.writeObject(student);
                System.out.println("我是客户端1,我将数据发送完毕");
                //关闭通道
                socket.shutdownOutput();
                //客户端需要通过输入流读取服务器端发送过来的消息
                is = socket.getInputStream();
                br = new BufferedReader(new InputStreamReader(is));
                String result = br.readLine();
                System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{           
                try {               
                    br.close();
                    is.close();
                    oos.close();
                    os.close();
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    ​
            }
        }
    }
    ​
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    ​
    import cn.bdqn.demo03.Student;
    ​
    public class Client2 {
        public static void main(String[] args) {
            Socket socket = null;
            OutputStream os = null;
            ObjectOutputStream oos = null;
            InputStream is = null;
            BufferedReader br = null;
            try {
                //创建通信链路的端点客户端套接字
                socket = new Socket("127.0.0.1", 8888);
                //获取输出流将数据发送出去
                os = socket.getOutputStream();
                Student student = new Student("李四", 23);
                oos = new ObjectOutputStream(os);
                oos.writeObject(student);
                System.out.println("我是客户端2,我将数据发送完毕");
                //关闭通道
                socket.shutdownOutput();
                //客户端需要通过输入流读取服务器端发送过来的消息
                is = socket.getInputStream();
                br = new BufferedReader(new InputStreamReader(is));
                String result = br.readLine();
                System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{           
                try {               
                    br.close();
                    is.close();
                    oos.close();
                    os.close();
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    ​
            }
        }
    }
    ​
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.ObjectOutputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    ​
    import cn.bdqn.demo03.Student;
    ​
    public class Client3 {
        public static void main(String[] args) {
            Socket socket = null;
            OutputStream os = null;
            ObjectOutputStream oos = null;
            InputStream is = null;
            BufferedReader br = null;
            try {
                //创建通信链路的端点客户端套接字
                socket = new Socket("127.0.0.1", 8888);
                //获取输出流将数据发送出去
                os = socket.getOutputStream();
                Student student = new Student("王五", 23);
                oos = new ObjectOutputStream(os);
                oos.writeObject(student);
                System.out.println("我是客户端3,我将数据发送完毕");
                //关闭通道
                socket.shutdownOutput();
                //客户端需要通过输入流读取服务器端发送过来的消息
                is = socket.getInputStream();
                br = new BufferedReader(new InputStreamReader(is));
                String result = br.readLine();
                System.out.println("我是客户端,接收到的服务器端响应信息为:"+result);
            } catch (UnknownHostException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{           
                try {               
                    br.close();
                    is.close();
                    oos.close();
                    os.close();
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    ​
            }
        }
    }
    ​
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    ​
    public class Server {
        /*
         * 多个客户端向服务器发送请求,服务器怎么办???
         * 
         * 
         * 客户端跟之前客户端做的事情没有任何改变
         *      客户端通过输出流发送请求信息
         *      客户端通过输入流获取服务器端的响应信息
         * 服务器端做的事情跟之前服务器端做的事情不一样
         *      服务器端循环去侦听客户端的请求,侦听到一个请求就会获取一个Socket类对象,
         * 将这个Socket类对象作为参数传递给服务器线程类的有参构造方法里去
         * 服务器线程类通过获取到的Socket类对象去执行原来服务器所做的事情
         *      通过输入流获取客户端的请求信息
         *      通过输出流发送响应信息给客户端
         * 
         */
        public static void main(String[] args) {
            
            ServerSocket ss = null;
            Socket socket = null;
            try {
                //创建ServerSocket类对象
                ss = new ServerSocket(8888);
                while(true){
                    socket = ss.accept();
                    //将获取到的socket对象传递到线程类中
                    ServerThread st = new ServerThread(socket);
                    st.start();
                }
                
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                
                try {
                    socket.close();
                    ss.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    ​
            }
        }
    ​
    }
    ​
    ​
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.ObjectInputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    ​
    public class ServerThread extends Thread {
    ​
        //声明一个Socket类型的属性
            private Socket socket;
    ​
            public ServerThread(Socket socket) {
                super();
                this.socket = socket;
            }
    ​
        
        @Override
        public void run() {
            
            InputStream is =null;
            ObjectInputStream ois =null;
            OutputStream os =null;  
            try {
                //通过返回的Socket对象调用方法获取一个输入流来读取客户端发送过来的消息
                is = socket.getInputStream();
                ois = new ObjectInputStream(is);
                Student student = (Student)ois.readObject();
                System.out.println("我这边是服务器:客户端发送给我的数据是:"+student);
    ​
                //关闭通道
                socket.shutdownInput();
    ​
                //服务器接收客户端消息后,需要给客户端一个响应信息
    ​
                os =socket.getOutputStream();
                String result = "获取的对象姓名和年龄正确";
                byte[] bytes = result.getBytes();
                os.write(bytes);
                System.out.println("给客户端的响应信息发送成功");
    ​
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                
                try {
                    os.close();
                    ois.close();
                    is.close();
                    socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
        }
    ​
    }
    import java.io.Serializable;
    ​
    public class Student implements Serializable {
        private String name;
        private int age;
    ​
        public Student() {
            super();
        }
    ​
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    ​
        public String getName() {
            return name;
        }
    ​
        public void setName(String name) {
            this.name = name;
        }
    ​
        public int getAge() {
            return age;
        }
    ​
        public void setAge(int age) {
            this.age = age;
        }
    ​
        @Override
        public String toString() {
            return "Student [name=" + name + ", age=" + age + "]";
        }
    ​
    }
    ​

    基于UDP协议的Socket编程

     

    基于UDP协议的Socket网络编程步骤

     

    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.SocketAddress;
    import java.net.SocketException;
    import java.util.Scanner;
    ​
    ​
    public class Receive {
    ​
        public static void main(String[] args) {
            /*
             * 示例06:升级示例05,发送方发送咨询问题,接收方回应咨询。
             * 
             * 接收方实现步骤如下: 
             * (1)创建DatagramPacket对象,准备接收封装的数据。
             * (2)创建DatagramSocket对象,接收数据保存于DatagramPacket对象中。
             * (3)利用DatagramPacket对象处理数据。
             */
            Scanner sc  = new Scanner(System.in);
            DatagramSocket ds = null;
            DatagramPacket dp = null;
            DatagramPacket dpto = null;
            // 创建DatagramPacket对象,用来准备接收数据
            byte[] buf = new byte[1024];
            dp = new DatagramPacket(buf, 1024);
        
            while(true){
                try {
                    // 创建DatagramSocket对象,接收数据
                    ds = new DatagramSocket(8800);
                    ds.receive(dp);
                    // 显示接收到的信息
                    String mess = new String(dp.getData(), 0, dp.getLength());
                    System.out.println(dp.getAddress().getHostAddress() + "说:" + mess);
    ​
                    String reply = sc.nextLine();
                    // 显示与本地对话框
                    System.out.println("我  说:" + reply);
                    // 创建DatagramPacket对象,封装数据
                    SocketAddress sa = dp.getSocketAddress();
                    dpto = new DatagramPacket(reply.getBytes(),
                            reply.getBytes().length, sa);
                    ds.send(dpto);
                } catch (SocketException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    ds.close();
                }
            }
    ​
        }
    ​
    }
    ​
    ​
    import java.io.IOException;
    import java.net.DatagramPacket;
    import java.net.DatagramSocket;
    import java.net.InetAddress;
    import java.net.SocketException;
    import java.net.UnknownHostException;
    import java.util.Scanner;
    ​
    public class Send {
        /*
         * 示例06:升级示例05,发送方发送咨询问题,接收方回应咨询。
         * 
         * 发送方实现步骤如下: 
         * (1)获取本地主机的InetAddress对象。 
         * (2)创建DatagramPacket对象,封装要发送的信息。
         * (3)利用DatagramSocket对象将DatagramPacket对象数据发送出去。
         */
    ​
        public static void main(String[] args) {
            Scanner sc = new Scanner(System.in);
            DatagramSocket ds = null;
            InetAddress ia = null;
            
            while(true){
                String mess = sc.nextLine();
                System.out.println("我说:" + mess);
                try {
                    // 获取本地主机地址
                    ia = InetAddress.getByName("localhost");
                    // 创建DatagramPacket对象,封装数据
                    DatagramPacket dp = new DatagramPacket(mess.getBytes(),
                            mess.getBytes().length, ia, 8800);
                    // 创建DatagramSocket对象,向服务器发送数据
                    ds = new DatagramSocket();
                    ds.send(dp);
    ​
                    byte[] buf = new byte[1024];
                    DatagramPacket dpre = new DatagramPacket(buf, buf.length);
                    ds.receive(dpre);
                    // 显示接收到的信息
                    String reply = new String(dpre.getData(), 0, dpre.getLength());
                    System.out.println(dpre.getAddress().getHostAddress() + "说:"
                            + reply);
                } catch (UnknownHostException e) {
                    e.printStackTrace();
                } catch (SocketException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    ds.close();
                }
            }
        }
    }
    ​
  • 相关阅读:
    maven的进阶学习
    2023年09月 C/C++(七级)真题解析#中国电子学会#全国青少年软件编程等级考试
    linux网络编程epoll详解
    几种“超强壮”的弱密码方案
    将信息传播至每个角落,政府信息发布系统解决方案
    Ubuntu18 无法加载登录界面【100%解决】
    offline RL | CQL:魔改 Bellman error 更新,得到 Q 函数 lower-bound
    Java数据类型:基本数据类型和引用数据类型
    Springboot整合logback多节点日志文件加端口号区分
    原来Spring能注入集合和Map的computeIfAbsent是这么好用!
  • 原文地址:https://blog.csdn.net/lmdbhf/article/details/126729597