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群交流群
有事请加群,有问题进群大家一起交流!

原文地址:https://www.cnblogs.com/huanzi-qch/p/15472037.html