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;
    /// <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();
}

连接效果

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/364631.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

分发糖果[困难]

优质博文&#xff1a;IT-BLOG-CN 一、题目 n个孩子站成一排。给你一个整数数组ratings表示每个孩子的评分。你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 【1】每个孩子至少分配到1个糖果。 【2】相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩…

JavaScript基础五对象 内置对象 Math.random()

内置对象-生成任意范围随机数 Math.random() 随机数函数&#xff0c; 返回一个0 - 1之间&#xff0c;并且包括0不包括1的随机小数 [0, 1&#xff09; 如何生成0-10的随机数呢&#xff1f; Math.floor(Math.random() * (10 1)) 放大11倍再向下取整 如何生成5-10的随机数&…

【智能算法】11种混沌映射算法+2种智能算法示范【鲸鱼WOA、灰狼GWO算法】

1 主要内容 混沌映射算法是我们在智能算法改进中常用到的方法&#xff0c;本程序充分考虑改进算法应用的便捷性&#xff0c;集成了11种混合映射算法&#xff0c;包括Singer、tent、Logistic、Cubic、chebyshev、Piecewise、sinusoidal、Sine、ICMIC、Circle、Bernoulli&#xf…

css实现按钮边框旋转

先上效果图 本质&#xff1a;一个矩形在两个矩形互相重叠遮盖形成的缝隙中旋转形成&#xff0c;注意css属性z-index层级关系 直接上代码 <div class"bg"><div class"button">按钮</div></div><style>.bg {width: 100%;heigh…

数字图像处理(实践篇)四十一 OpenCV-Python 使用sift算法检测图像上的特征点实践

目录 一 涉及的函数 二 实践 2004年,D.Lowe在论文Distinctive Image Features from Scale-Invariant Keypoints中提出了一种新算法,即尺度不变特征变换 (SIFT),该算法提取关键点并计算其描述符。SIFT提取图像的局部特征,在尺度空间寻找极值点,并提取出其位置尺度和方向…

绝地求生:“龙腾”通行证和新空投任务内容一览:二十级依然有图纸!

大家好&#xff0c;27.2版本终于更新完了&#xff0c;先为大家带来这次龙腾通行证的详细内容&#xff0c;显放上详细的兑换点数大家可以慢慢看。 省流: 通行证分支3仍然可解锁图纸和500G-COIN奖励&#xff0c;空投任务也可以通过做很简单的游戏任务70代币兑换获得1张图纸。 这次…

main函数中参数argc和argv用法解析

1 基础 argc 是 argument count 的缩写&#xff0c;表示传入main函数的参数个数&#xff1b; argv 是 argument vector 的缩写&#xff0c;表示传入main函数的参数序列或指针&#xff0c;并且第一个参数argv[0]一定是程序的名称&#xff0c;并且包含了程序所在的完整路径&…

vue 发布自己的npm组件

1、在项目任意位置创建index.ts文件 2、导入要到处的组件&#xff0c;使用vue提供的install 功能全局挂在&#xff1b; import GWButton from "/views/GWButton.vue"; import GWAbout from "/views/AboutView.vue";const components {GWButton,GWAbout, …

canvas路径剪裁clip(图文示例)

查看专栏目录 canvas实例应用100专栏&#xff0c;提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重…

python执行linux系统命令的三种方式

前言 这是我在这个网站整理的笔记,有错误的地方请指出&#xff0c;关注我&#xff0c;接下来还会持续更新。 作者&#xff1a;神的孩子都在歌唱 1. 使用os.system 无法获取命令执行后的返回信息 import osos.system(ls)2. 使用os.popen 能够获取命令执行后的返回信息 impor…

什么是SDN-软件定义网络

知识改变命运&#xff0c;技术就是要分享&#xff0c;有问题随时联系&#xff0c;免费答疑&#xff0c;欢迎联系&#xff01; 厦门微思网络​​​​​​ https://www.xmws.cn 华为认证\华为HCIA-Datacom\华为HCIP-Datacom\华为HCIE-Datacom Linux\RHCE\RHCE 9.0\RHCA\ Oracle O…

力扣之2648.生成 斐波那契数列(yield)

/*** return {Generator<number>}*/ var fibGenerator function*() {let a 0,b 1;yield 0; // 返回 0&#xff0c;并暂停执行yield 1; // 返回 1&#xff0c;并暂停执行while(true) {yield a b; // 返回 a b&#xff0c;并暂停执行[a, b] [b, a b]; // 更新 a 和 …

大力说视频号第五课:千粉才能直播带货?如何做到

腾讯对直播带货设置了条件&#xff1a;要么你的账号得有1000个粉丝&#xff0c;要么你得开通视频号小店。 对于那些还没有开通视频号小店的用户&#xff0c;他们要想申请直播带货&#xff0c;就必须完成微信实名认证、拥有1000个以上的有效关注者&#xff0c;并缴纳一笔保证金。…

船员投保的数学模型(MATLAB求解)

1.问题描述 劳动工伤事故&#xff0c;即我们平时所说的“工伤事故”&#xff0c;也称职业伤害&#xff0c;是指劳动者在生产岗位上&#xff0c;从事与生产劳动有关的工作中发生的人身伤害事故、急性中毒事故或职业病。船员劳动工伤事故是指船员在船舶生产岗位上&#xff0c;从…

《基于“源启+”的应用重构白皮书》

当前&#xff0c;行业数字化转型驶入“深水区”&#xff0c;全新的市场竞争格局对行业发展提出更高的要求&#xff0c;企业高质量发展需要借助新架构新应用重新定义数字生产力&#xff0c;重塑商业模式与市场核心竞争力。 在中国电子主办&#xff0c;中电金信承办的“数字原生向…

SpringBoot实战(二十六)集成SFTP

目录 一、SFTP简介二、SpringBoot 集成2.1 Maven 依赖2.2 application.yml 配置2.3 DemoController.java 接口2.4 SftpService.java2.5 DemoServiceImpl.java 实现类2.6 SftpUtils.java 工具类2.7 执行结果1&#xff09;上传文件2&#xff09;下载文件3&#xff09;重命名文件&…

go并发编程-介绍与Goroutine使用

1. 并发介绍 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中的多个…

ElementUI 组件:Layout布局(el-row、el-col)

ElementUI安装与使用指南 Layout布局 点击下载learnelementuispringboot项目源码 效果图 el-row_el-col.vue页面效果图 项目里el-row_el-col.vue代码 <script> export default {name:el-row_el-col 布局 }</script><template><div class"roo…

【Vue】2-14、插槽 自定义指令

一、插槽 插槽&#xff08;Slot&#xff09;是 vue 为组件的封装者提供的能力。允许封装者在封装组件时&#xff0c;把不确定的&#xff0c;希望由用户指定的部分定义为插槽。 <template><div class"app-container"><h1>App 根组件</h1>&…

Java打印图形 九九乘法表

目录 双重循环九九乘法表打印长方形打印平行四边形打印三角形打印菱形打印空心菱形 三重循坏百钱买百鸡 双重循环 九九乘法表 在Java中&#xff0c;你可以使用嵌套的for循环来打印九九乘法表。以下是一个简单的示例&#xff1a; public class Main {public static void main…
最新文章