zoukankan      html  css  js  c++  java
  • mooc_java Socket

    Socket通信,TCP协议是面向连接,可靠的,有序的,以字节流的方式发送数据;
    基于TCP协议实现网络通信的类
    客户端的Socket类 服务器端的ServerSocket类

     

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    实现基于TCP的Socket通信:

    在服务器端,创建ServerSocket对象,绑定监听端口;通过accept方法监听客户请求;建立连接后,通过输入流读取客户端发送的请求;通过输入流向客户端发送响应信息;关闭相关资源。

    public class Server {
    public static void main(String[] args) {
        try {
            //创建一个服务器端Socket,指定绑定的端口,
            ServerSocket serverSocket=new ServerSocket(8888);
            //调用accept()监听,等待客户端的连接
            System.out.println("服务器即将启动 ,等待客户端的连接");
            Socket socket=serverSocket.accept();
            //获取输入流,读取客户端信息
            InputStream is=socket.getInputStream();
            InputStreamReader isr=new InputStreamReader(is);//将字节流转为字符流
            BufferedReader br=new BufferedReader(isr);//为输入流添加缓冲
            String info=null;
            while((info=br.readLine())!=null){
                System.out.println("服务器,客户端:"+info);
            }
            socket.shutdownInput();
            
            br.close();
            isr.close();
            is.close();
            socket.close();
            serverSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    }

    在客户端,创建Socket对象,指明要连接的服务器地址和端口号;建立连接后,通过输出流想服务器端发送请求信息;通过输入流获取服务器响应的信息;关闭相关资源。

    public class Client {
    public static void main(String[] args) {
        try {
            //创建客户端Socket,指定服务器地址和端口
            Socket socket=new Socket("localhost",8888);
            //获取输出流,向服务器发送信息
            OutputStream os=socket.getOutputStream();//字节输出流
            PrintWriter pw=new PrintWriter(os);//将输出流包装成打印流
            pw.write("用户名:admin;密码:123"); 
            pw.flush();//刷新缓存,向服务器端提供信息
            socket.shutdownOutput();//关闭输出流
            
            pw.close();
            os.close();
            socket.close();
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    }

    服务器响应客户端:

    //获取输入流,响应客户端的请求
    OutputStream os=socket.getOutputStream();
    PrintWriter pw=new PrintWriter(os);//包装为打印流
    pw.write("欢迎您");
    pw.flush();//调用flush方法将缓冲输出
    pw.close();
    os.close();

    客户端:

    //获取输入流,读取服务器端的响应信息
    InputStream is=socket.getInputStream();
    BufferedReader br=new BufferedReader(new InputStreamReader(is));
    String info=null;
    while((info=br.readLine())!=null){
        System.out.println("客户端,服务器:"+info);
    }
    br.close();
    is.close();

    使用多线程实现多客户端的通信:

    ServerTherad类

    public class ServerThread extends Thread{
        Socket socket=null;
        public ServerThread(Socket socket){
            this.socket=socket;//初始化和本线程相关的socket
        }
        //线程执行的操作,响应客户端的请求
        public void run(){
            //获取输入流,读取客户端信息
            InputStream is=null;
            InputStreamReader isr=null;
            BufferedReader br=null;
            //获取输入流,响应客户端的请求
            OutputStream os=null;
            PrintWriter pw=null;
            try {
                is = socket.getInputStream();
                isr = new InputStreamReader(is);
                br = new BufferedReader(isr);
                String info=null;
                while((info=br.readLine())!=null){
                    System.out.println("服务器,客户端:"+info);
                }
                socket.shutdownInput();
                os = socket.getOutputStream();
                pw = new PrintWriter(os);
                pw.write("欢迎您");
                pw.flush();//调用flush方法将缓冲输出
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally {
                try {
                    if(pw!=null)
                        pw.close();
                    if(os!=null)
                        os.close();
                    if(br!=null)
                        br.close();
                    if(isr!=null)
                        isr.close();
                    if(is!=null)
                        is.close();
                    if(socket!=null)
                        socket.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

    Server类

    public class Server {
    public static void main(String[] args) {
        try {
            ServerSocket serverSocket=new ServerSocket(8888);
            Socket socket=null;
            //记录客户端的数量
            int count=0;
            System.out.println("服务器即将启动 ,等待客户端的连接");
            //循环监听等待客户端的连接
            while(true){
                socket=serverSocket.accept();
                //创建一个线程
                ServerThread serverThread=new ServerThread(socket);
                //启动线程
                serverThread.start();
                
                count++;
                System.out.println("客户端的数量"+count);
                InetAddress address=socket.getInetAddress();
                System.out.print("当前客户端的IP:"+address.getHostAddress());
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    }

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    实现基于UDP的Socket通信:

    UDP协议(用户数据报协议)是无连接的,不可靠的,无序的,速度相对较快,以数据报作为数据传输的载体:
      在进行数据传输时,将数据定义成数据报(Datagram),在数据报中致命数据要达到 的Socket(主机地址和端口号),然后发送数据报。
    相关操作类:
    DatagramPacket:数据报包   DatagramSocket:进行 端到端通信的类
    服务器端:
    创建DatagramSocket,指定端口号
    创建DatagramPacket
    接收客户端发送的数据信息
    读取数据
    客户端:
    定义发送信息
    创建DatagramPacket,包含要发送的信息
    创建DatagramSocket

    --------------------------

    实现基于UDP的用户登录

    服务器端要早于客户端启动

    //服务器端
    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.接收客户端发送的数据
            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();
        }
    //客户端
    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);//接收并保存在packet2中
            //3.读取信息
            String reply=new String(data2, 0,packet2.getLength());
            System.out.println("客户端:服务器"+reply);
            //4.关闭资源
            socket.close();
        }
    在平凡中坚持前行,总有一天,会遇见优秀的自己
  • 相关阅读:
    PHP观察者模式 (转)
    PHP单例模式 (转)
    PHP解决并发问题的几种实现(转)
    php结合redis实现高并发下的抢购、秒杀功能 (转)
    使用 redis 减少 秒杀库存 超卖思路 (转)
    mysql视图学习总结(转)
    mysql 存储过程
    PHP中的魔术方法和关键字
    bzoj3462DZY Loves Math II
    bzoj1453[Wc]Dface双面棋盘
  • 原文地址:https://www.cnblogs.com/mao-19/p/4963569.html
Copyright © 2011-2022 走看看