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){
            mutexConnect.ReleaseMutex();
            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();
}

连接效果

在这里插入图片描述

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
wincc是西门子公司开发的一款人机界面软件,用于监控和控制工业过程。而Modbus TCP是一种通信协议,用于在工业自动化中进行设备之间的数据交换。 如果在wincc中使用Modbus TCP连接时出现掉线的情况,可能有以下几个原因: 1. 网络问题:可能是网络连接不稳定或者出现了网络延迟,导致wincc与Modbus TCP设备之间的通信中断。解决方法是检查网络连接是否正常,可以尝试重新连接或者重新启动网络设备。 2. Modbus TCP设备故障:如果Modbus TCP设备本身出现故障,例如断电或者设备崩溃,那么wincc无法与其进行通信。解决方法是检查设备状态,确保设备正常运行。 3. 配置错误:可能是在wincc中配置Modbus TCP连接时出现了错误,导致无法建立正确的通信。解决方法是检查wincc中Modbus TCP连接的配置,确保IP地址、端口号、数据类型和寄存器地址等参数设置正确。 4. 软件或版本兼容性问题:有时候,wincc和Modbus TCP设备的软件版本或兼容性存在问题,导致连接中断。解决方法是检查软件版本要求,并升级或降级软件版本以解决兼容性问题。 总之,出现wincc和Modbus TCP连接掉线的情况可能是由于网络问题、设备故障、配置错误或兼容性问题等原因导致的。通过检查网络连接、设备状态、配置和软件版本等方面,可以解决这些问题,确保连接正常稳定地运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值