zoukankan      html  css  js  c++  java
  • Java基础之Socket通信简单实例

      前言

      Java网络编程之Socket套接字,Socket套接字使用TCP提供了两台计算机之间的通信机制

      TCP(英语:Transmission Control Protocol,传输控制协议) 是一种面向连接的、可靠的、基于字节流的传输层通信协议,TCP 层是位于 IP 层之上,应用层之下的中间层。TCP 保障了两个应用程序之间的可靠通信。通常用于互联网协议,被称 TCP / IP

      本文记录Java的Socket通信简单实例

      服务端

    package cn.huanzi.qch.util;
    
    import java.io.BufferedReader;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.nio.charset.StandardCharsets;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    /**
     * Socket服务端
     */
    public class SocketServer {
        public static void main(String[] args) throws Exception{
            //服务端在20006端口监听客户端请求的TCP连接
            ServerSocket server = new ServerSocket(20086);
            Socket client;
    
            System.out.println("服务端启动成功!");
    
            //如果使用多线程,那就需要线程池,防止并发过高时创建过多线程耗尽资源
            ExecutorService threadPool = Executors.newFixedThreadPool(10);
    
            while (true) {
                //等待客户端的连接,如果没有获取连接
                client = server.accept();
    
                //为每个客户端连接开启一个线程
                threadPool.submit(new ServerThread(client));
            }
        }
    }
    
    /**
     * 与客户端连接操作异步线程
     */
    class ServerThread implements Runnable {
        //socket连接
        private final Socket client;
    
        public ServerThread(Socket client){
            this.client = client;
        }
    
        @Override
        public void run() {
            try{
                System.out.println("与客户端["+client.getInetAddress()+":"+client.getPort()+"]连接成功!");
    
                //获取Socket的输出流,用来向客户端发送数据
                PrintStream out = new PrintStream(client.getOutputStream());
                //获取Socket的输入流,用来接收从客户端发送过来的数据
                BufferedReader buf = new BufferedReader(new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8));
    
                boolean flag =true;
                while(flag){
                    //接收从客户端发送过来的数据
                    String msg = buf.readLine();
    
                    //约定:通过约定符号'exit'通知服务端关闭与客户端的连接
                    if("exit".equals(msg)){
                        flag = false;
                    }else{
                        //将接收到的字符串前面加上echo,发送到对应的客户端
                        out.println("echo:"+msg);
                    }
                    System.out.println("收到客户端["+client.getInetAddress()+":"+client.getPort()+"]消息:"+msg);
                }
    
                System.out.println("与客户端["+client.getInetAddress()+":"+client.getPort()+"]断开连接...");
    
                out.close();
                buf.close();
                client.close();
            }catch(Exception e){
                System.err.println("Socket连接异常...");
                e.printStackTrace();
            }
        }
    }

      客户端

    package cn.huanzi.qch.util;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.PrintStream;
    import java.net.Socket;
    import java.net.SocketTimeoutException;
    import java.nio.charset.StandardCharsets;
    
    /**
     * Socket客户端
     */
    public class SocketClient {
        //地址
        private static final String host = "127.0.0.1";
    
        //端口
        private static final int port = 20086;
    
        //Socket连接
        private static Socket client;
    
        //Socket的输出流,用来发送数据到服务端
        private static PrintStream out;
    
        //Socket的输入流,用来接收从服务端发送过来的数据
        private static BufferedReader buf;
    
        /**
         * 初始化Socket连接
         */
        private static void init() throws IOException {
            //客户端请求与 host 在 port 端口建立TCP连接
            client = new Socket(host, port);
            //获取Socket的输出流
            out = new PrintStream(client.getOutputStream());
            //获取Socket的输入流
            buf = new BufferedReader(new InputStreamReader(client.getInputStream(), StandardCharsets.UTF_8));
        }
    
        /**
         * 发送消息
         */
        private static void sendMsg(String msg) throws IOException {
            try{
                //发送数据到服务端
                out.println(msg);
            }catch (Exception e){
                //打印日志,并重连Socket
                System.err.println("Socket连接异常,正在重新连接...");
                e.printStackTrace();
    
                init();
    
                //重新发送数据数据到服务端
                out.println(msg);
            }
    
    
            //等待服务端响应
            try{
                String echo = buf.readLine();
                System.out.println("收到服务端回应:"+echo);
            }catch(SocketTimeoutException e){
                System.err.println("服务端响应超时...");
                e.printStackTrace();
            } catch (IOException e) {
                System.err.println("服务端响应异常...");
                e.printStackTrace();
            }
        }
    
        /**
         * 关闭Socket连接
         * 约定:通过约定符号'exit'通知服务端关闭与客户端的连接
         */
        private static void close() throws IOException {
            //通知服务端结束与客户端的连接异步线程
            out.println("exit");
    
            out.close();
            buf.close();
            client.close();
        }
    
    
        public static void main(String[] args) throws IOException, InterruptedException {
            init();
    
            for (int i = 1; i <= 5; i++) {
                sendMsg("你好,我是消息"+i);
                Thread.sleep(2000);//休眠
            }
    
            close();
        }
    }

      效果

      先运行服务端,再运行客户端

      客户端

     

      服务端

     

      后记

      为了减少传输数据的大小,可以通过约定报文格式,传输16进制数据,例如:OxFF 01 3A 4D

      Java的Socket通信简单实例暂时先记录到这,后续再进行补充

    版权声明

    作者:huanzi-qch
    若标题中有“转载”字样,则本文版权归原作者所有。若无转载字样,本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利.

    AD广告位(长期招租,如有需要请私信)

    【基塔后台】免费后台管理系统,低代码快速搭建管理后台

    【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年74元!
    【腾讯云】境外1核2G服务器低至2折,半价续费券限量免费领取!
    【腾讯云】星星海SA2云服务器,1核2G首年99元起,高性价比首选!
    【腾讯云】中小企业福利专场,多款刚需产品,满足企业通用场景需求,云服务器2.5折起!

    【阿里云】新老用户同享,上云优化聚集地!
    【阿里云】最新活动页,上新必买抢先知,劲爆优惠不错过!
    【阿里云】轻量应用服务器2核2G 低至60元/年起!香港与海外服务器最低24元/月起!
    【阿里云】ECS实例升级、续费,享低至 6.3折 限时折扣!

    捐献、打赏

    请注意:作者五行缺钱,如果喜欢这篇文章,请随意打赏!

    支付宝

    微信


    QQ群交流群

    QQ群交流群
    有事请加群,有问题进群大家一起交流!

  • 相关阅读:
    Python之数学(math)和随机数(random)
    《图解HTTP》读书笔记
    leetcode1008
    leetcode1007
    leetcode1006
    leetcode1005
    leetcode218
    leetcode212
    leetcode149
    leetcode140
  • 原文地址:https://www.cnblogs.com/huanzi-qch/p/15472037.html
Copyright © 2011-2022 走看看