TCP 连接掉线自动重连

文章目录

    • 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;
    /// 
    /// 需要使用锁来防止多线程抢连
    /// 
    private Mutex mutexConnect = new Mutex(false, "MutexForConnect");


    /// 
    /// 与交互的执行者
    /// 
    /// 本地ip地址字符串
    /// ip地址字符串
    /// 端口号

    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);     // 服务器的地址
    }

    /// 
    /// 对Connect函数加锁(因为有多个线程需要连接,会报错)
    /// 
    /// 若连接成功则返回socket对象,否则返回空
    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对象,否则返回空
    }

    /// 
    /// 建立与服务器的TCP/IP连接
    /// 
    /// 成功返回true,反之返回false
    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();
}

连接效果

TCP 连接掉线自动重连_第1张图片

你可能感兴趣的:(C#项目,笔记,tcp/ip,网络,c#)