zoukankan      html  css  js  c++  java
  • Java Socket 通信之多线程

    一、简单的客户端与服务器交互(客户端向服务器发送数据,服务器将数据再返回给客户端)

    服务端

    * 1、创建服务器 指定端口 ServerSocket(int port)
    * 2、接收客户端连接 阻塞时
    * 3、发送数据
    * 接收多个客户端

    Mulityserver.java

    package cn.Tcp;
    /*
     * 服务端
     * 1、创建服务器 指定端口   ServerSocket(int port)
     * 2、接收客户端连接   阻塞时
     * 3、发送数据
     * 接收多个客户端
     */
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    public class Mulityserver {
        public static void main(String[] args) throws IOException {
            //1、创建服务器 指定端口   ServerSocket(int port)
            ServerSocket server=new ServerSocket(8488);
            //2、接收客户端连接   阻塞时
            while(true) {  //死循环  一个accept() 一个客户端
                Socket socket=server.accept();
                System.out.println("一个客户端建立连接");
                //3、发送数据
                String msg="欢迎使用";
                //输出流
                
                DataOutputStream dos=new DataOutputStream(socket.getOutputStream());
                dos.writeUTF(msg);
                dos.flush();
            }
        }
    }

    客户端

    Client.java

    package cn.Tcp;
    
    import java.io.DataInputStream;
    import java.io.IOException;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class Client {
        public static void main(String[] args) throws UnknownHostException, IOException {
            //1、创建客户端 必须指定服务器+端口 此时就在连接
            Socket client=new Socket("localhost",8488);
            //2、接收数据
            DataInputStream dis =new DataInputStream(client.getInputStream());
            String     echo=dis.readUTF();
            System.out.println(echo);
            
        }
    }

    效果:

    二、多线程实现客户端与服务器端交互(客户端不断的发送,服务器不断的返回)

    1)关闭流的方法

    CloseUtil.java

    package chatdemo02;
    
    import java.io.Closeable;
    import java.io.IOException;
    
    /*
     * 关闭流的方法
     */
    public class CloseUtil {
        public static void closeAll(Closeable... io) {
            for(Closeable temp:io) {
                    try {
                        if(null!=temp) {
                        temp.close();
                    } 
                    }    catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    
                }
            }
        }
    }

    2)发送数据的线程

    Send.java

    package chatdemo02;
    
    import java.io.BufferedReader;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.Socket;
    
    /*
     * 发送数据  线程 
     */
    public class Send implements Runnable {
        //控制台输入流
        private BufferedReader console;
        //管道输出流
        private DataOutputStream dos;
        //控制线程
        private boolean isRunning=true;
        
        public Send() {
            console=new BufferedReader(new InputStreamReader(System.in));
            
        }
        public Send(Socket client) {
            this();
            try {
                dos=new DataOutputStream(client.getOutputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                isRunning=false;
                CloseUtil.closeAll(dos,console);
            }
        }
        
        private String getMsgFromConsole() {
            try {
                return console.readLine();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            return "";
        }
    /*
     * 1、从控制台接收数据
     * 2、发送数据
     */
        public void send() {
            String msg=getMsgFromConsole();
            if(null!=msg&&  !msg.equals("")) {
                try {
                    dos.writeUTF(msg);
                    dos.flush();   //强制刷新
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    isRunning=false;
                    CloseUtil.closeAll(dos,console);
    
                }
            }
        }
        @Override
        public void run() {
            // 线程体
            while(isRunning) {
                send();
            }
        }
    
    }

    3)接收数据的线程

    Receive.java

    package chatdemo02;
    /*
     * 接收线程
     */
    
    import java.io.DataInputStream;
    import java.io.IOException;
    import java.net.Socket;
    
    public class Receive implements Runnable {
        //输入流
        private DataInputStream dis;
        //线程标识
        private boolean isRunning=true;
        
        public Receive() {
            
        }
    
        public Receive(Socket client) {
            try {
                dis=new DataInputStream(client.getInputStream());
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                isRunning=false;
                CloseUtil.closeAll(dis);
            }
        }
        
        /*
         * 接收数据
         */
        public String receive() {
            String msg="";
            try {
                msg=dis.readUTF();
                
            } catch (IOException e) {
                //e.printStackTrace();
                isRunning=false;
                CloseUtil.closeAll(dis);
                
            }
            return msg;
        }
    
        @Override
        public void run() {
            //线程体
            while(isRunning) {
                System.out.println(receive());
            }
        }
    
    }

    4)服务端

    Server.java

    package chatdemo02;
    
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    
    /*
     * 创建服务器
     * 写出数据 :输出流
     * 读取数据:输入流
     */
    public class Server {
        public static void main(String[] args) throws IOException {
            ServerSocket server=new ServerSocket(9999);
            Socket client=server.accept();
            
            //写出数据
            //输入流
            DataInputStream dis=new DataInputStream(client.getInputStream());
            String msg=dis.readUTF();
            System.out.println(msg);
            
            //输出流    
            DataOutputStream dos=new DataOutputStream(client.getOutputStream());
            dos.writeUTF("服务器----->"+msg);
            dos.flush();
        }
    }

    5)客户端

    Client.java

    package chatdemo02;
    
    import java.io.BufferedReader;
    import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    /*
     * 创建客户端  :发送数据+接收数据
     * 写出数据 :输出流
     * 读取数据:输入流
     * 输入流输出流在同一个线程内应该独立处理
     * 
     * 
     * 
     */
    public class Client {
        public static void main(String[] args) throws UnknownHostException, IOException {
            Socket client=new Socket("localhost",9984);
            //控制台输入流
            new Thread(new Send(client)).start();   //一条路径
            new Thread(new Receive(client)).start(); 
            
        }
        
    }

    运行 Server.java    Client.java   效果如下:

  • 相关阅读:
    想让进程后台运行,试试Linux的nohup命令,3分钟学会。
    面试官:你能说一下Redis的常见应用场景吗?
    面试被问MySQL 主从复制,怎么破?
    Spring Boot 解决跨域问题的 3 种方案!
    Kafka如果丢了消息,怎么处理的?
    惊呆,这样操作 Nginx 并发数就能达到3w?
    easyexcel 自动设置列宽(转)
    Ubuntu18.04自适应VMware调整桌面大小
    IDEA将maven项目打包时同时带上项目的maven依赖(转)
    python 定时框架APScheduler
  • 原文地址:https://www.cnblogs.com/ssxblog/p/11272666.html
Copyright © 2011-2022 走看看