TCP 连接掉线自动重连


TCP 接收数据时防止掉线。TCP 连接掉线自动重连。多线程环境下TCP掉线自动重连。
欢迎讨论更好的方法!

TCP 连接掉线自动重连

定义

定义一个类,以编写TCP连接函数Connect(),并且:

初始化时保存TCP连接的基本信息,在重连时不需要再次输入参数;
编写自动重连函数TryToConnect()

internal class Receiver
{
   
    private Socket clientConn;
    private string ip, myIP;
    private int port;
    private EndPoint point, myPoint;
    /// <summary>
    /// 需要使用锁来防止多线程抢连
    /// </summary>
    private Mutex mutexConnect = new Mutex(false, "MutexForConnect");


    /// <summary>
    /// 与交互的执行者
    /// </summary>
    /// <param name="myIP">本地ip地址字符串</param>
    /// <param name="ip">ip地址字符串</param>
    /// <param name="port">端口号</param>

    public Receiver(in string myIP, in string ip, in int port)
    {
   
        // 保存记录
        this.myIP = myIP;
        this.ip = ip;
        this.port = port;
        // 设置连接
        myPoint = new IPEndPoint(IPAddress.Parse(myIP), 0);    // 本地IP,0表示任意端口
        point = new IPEndPoint(IPAddress.Parse(ip), port);     // 服务器的地址
    }

    /// <summary>
    /// 对Connect函数加锁(因为有多个线程需要连接,会报错)
    /// </summary>
    /// <returns>若连接成功则返回socket对象,否则返回空</returns>
    public Socket TryToConnect()
    {
   
        // 如果已连接,直接返回了。
        if (!(clientConn is null) && clientConn.Connected) return clientConn;

        mutexConnect.WaitOne();             // 阻塞,每次连接一个。等进入者释放锁再进。
        // 如果刚才未连接,但是另一个【进入进程】先connect了,那就返回了。
        if (!(clientConn is null) && clientConn.Connected) return clientConn;
        bool flag = Connect();              // 【进入进程】发起连接
        Thread.Sleep(1000);                 // 防止过于频繁的连接,每秒进一个
        mutexConnect.ReleaseMutex();        // 【进入进程】释放锁

        return flag ? clientConn : null;    // 若连接成功则返回socket对象,否则返回空
    }

    /// <summary>
    /// 建立与服务器的TCP/IP连接
    /// </summary>
    /// <returns>成功返回true,反之返回false</returns>
    public Boolean Connect()
    {
   
        Console.Write($"({
     ip} {
     port}) 连接中...");
        //创建一个新的Socket对象
        clientConn = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        // 建立TCP / IP连接
        try
        {
   
            clientConn.Bind(myPoint);         //绑定本地IP,多IP防止串(若无此IP则可能抛出异常)                            
            clientConn.Connect(point);        //尝试连接
            Console.WriteLine("连接成功");
            return true;
        }
        catch (Exception)
        {
   
            Console.WriteLine("连接失败");
            clientConn.Close();
            clientConn.Dispose();
            return false;
        }
    }
}

使用

此处仅用主线程模拟。但实际上,多个线程使用连接语句也是OK的。

static void Main(string[] args)
{
   
    Receiver receiver = new Receiver(myIP: "192.168.100.10", ip: "192.168.100.1", port: 2003);

    // 连接
    Socket conn = null;
    while (conn is null) conn = receiver.TryToConnect();    // 如果没连上,就阻塞(因为不连上就无法进行后续工作)
    
    // 接收数据
    int toReadLen = 20;                                 	// 准备接收的byte数据长度
    byte[] rawData = new byte[toReadLen];               	// 接收数据的byte数组
    int len = conn.Receive(rawData, 0, toReadLen, SocketFlags.None);            // 接收到扫码器传来的信息
    while (len < toReadLen)
        len += conn.Receive(rawData, len, toReadLen - len, SocketFlags.None);   // 不足时,继续接收直到指定长度

    // 此处用于处理接收到的信息
    Console.WriteLine(BitConverter.ToString(rawData, 0, len));

    Console.ReadLine();
}

连接效果

在这里插入图片描述

相关推荐

  1. MySQL数据库连接超时和自动

    2024-02-02 20:26:03       34 阅读
  2. .NET6 RabbitMQ自动

    2024-02-02 20:26:03       41 阅读
  3. Qt 实现TCP 协议的断开

    2024-02-02 20:26:03       14 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-02-02 20:26:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-02 20:26:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-02 20:26:03       19 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-02 20:26:03       20 阅读

热门阅读

  1. 如何获取时间戳

    2024-02-02 20:26:03       30 阅读
  2. 浏览器唯一标识(浏览器指纹)fingerprintjs

    2024-02-02 20:26:03       34 阅读
  3. C#实现windows系统重启、关机

    2024-02-02 20:26:03       36 阅读
  4. C# 发送邮件

    2024-02-02 20:26:03       33 阅读
  5. 《Vite 基础知识》基于 Vite 的组件库框架搭建

    2024-02-02 20:26:03       37 阅读
  6. c语言 ceil() 函数

    2024-02-02 20:26:03       29 阅读
  7. 跨域访问支持(Spring Boot、Nginx、浏览器)

    2024-02-02 20:26:03       33 阅读
  8. 手写实现call、apply和bind函数

    2024-02-02 20:26:03       30 阅读
  9. Unity之延迟函数

    2024-02-02 20:26:03       35 阅读