前言


最近在写一个透传项目,需要实现一个TCPClient模式的透传。在没有连接上时会去不断发起连接直至连接成功, 还有断连后又会不断发起请求连接,直至再次连接成功。 作为小白,第一反应就是去百度,结果百度搜索出来的,全是CSDN,而且清一色都是上来贴一大堆代码,令人头晕,还一大堆重复的,越看越烦而且搜索无果。

既然没有路,那就由我自己来开辟!


连接成功前进行不断发起请求连接

其实这个功能思路非常简单,无非就是 尝试连接=>连接失败=>重连(连接成功就跳出)。

用代码写出来:

//创建一个新的Socket对象
Socket client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp)
try
{client.Connect(IPAddress.Parse(IP地址), 端口号);//尝试连接
}
catch
{client.Close();//先关闭/*使用新的客户端资源覆盖,上一个已经废弃。如果继续使用以前的资源进行连接,即使参数正确,服务器全部打开也会无法连接*/client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);client.Connect(IPAddress.Parse(IP地址), 端口号);//尝试连接
}复制代码

而这上面仅是进行一次失败重连,如果再失败怎么办?所以我们要不断重复这个步骤。加一层while循环让它不断进行重连。 代码如下:

//创建一个新的Socket对象
Socket client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp)
while(true)//无限循环
{try{client.Connect(IPAddress.Parse(IP地址), 端口号);//尝试连接,失败则会跳去catchbreak;//在此处加上break,成功就跳出循环,避免死循环}catch{client.Close();//先关闭/*使用新的客户端资源覆盖,上一个已经废弃。如果继续使用以前的资源进行连接,即使参数正确,服务器全部打开也会无法连接*/client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);}
}复制代码

其实这么写,就已经实现了我们初步的功能,客户端会进行不断地连接,直至成功连上服务器。但是,这里有个很严重的问题,如果一直没连上,一直在执行这一步重连,程序会卡死在这里。 所以我们需要额外多开个子线程去执行这一步操作。

//创建一个新的Socket对象
Socket client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp)
//将方法写进线程中
Thread thread=new Thread(() =>
{while(true)//无限循环{try{client.Connect(IPAddress.Parse(IP地址), 端口号);//尝试连接,失败则会跳去catchbreak;//在此处加上break,成功就跳出循环,避免死循环}catch{client.Close();//先关闭/*使用新的客户端资源覆盖,上一个已经废弃。如果继续使用以前的资源进行连接,即使参数正确, 服务器全部打开也会无法连接*/client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);Thread.Sleep(1000);//等待1s再去重连}}
});
thread.IsBackground = true;//设置为后台线程,在程序退出时自己会自动释放
thread.Start();//开始执行线程
复制代码

即使一直连不上也不会使程序卡死,会一直进行重连直到连上服务器。但是我们的问题还没解决。那就是 循环结束问题。这部分尝试不断连接,while循环的条件是true,无限循环,就会导致即使连上后,虽然break,但是线程没有结束,还是会继续去进行无限循环。我们需要重新设置循环中止条件。

代码如下:

//创建一个新的Socket对象
Socket client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp)
public static bool IsConnet=true;//判断是否成功连接,设置为全局变量,方便随时控制
//将方法写进线程中
Thread thread=new Thread(() =>
{while(IsConnet)//循环{try{client.Connect(IPAddress.Parse(IP地址), 端口号);//尝试连接,失败则会跳去catchIsConnet=false;//成功连接后修改bool值为false,这样下一步循环就不再执行。break;//在此处加上break,成功就跳出循环,避免死循环}catch{client.Close();//先关闭/*使用新的客户端资源覆盖,上一个已经废弃。如果继续使用以前的资源进行连接,即使参数正确, 服务器全部打开也会无法连接*/client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);Thread.Sleep(1000);//等待1s再去重连}}
});
thread.IsBackground = true;//设置为后台线程,在程序退出时自己会自动释放
thread.Start();//开始执行线程
复制代码

这样就不会再有无限循环的问题了。至此,我们已经完成了功能的一半,这部分已经实现了连接前的不断请求连接,那么连接后又断开呢?很显然,如果在连接后再断开,我们无法进行重连。
另一半就要实现 断线重连。


断线重连

这个思路同样很简单,就是服务器断开->调用连接方法->不断连接
连接方法就是我们上一步写过的功能,我们已经实现不断连接了,我们要将上一步的功能封装成一个方法体去调用就可以了。
连接上服务器后,就是个不断接收的过程,所以也需要多开一个线程去不断接收消息。 代码如下:

//注意,这里的开始部分还是上一步的代码,只不过嵌进了方法体
public void Connet(string Iptxt,int Port)//接收参数是目标ip地址和目标端口号。客户端无须关心本地端口号
{//创建一个新的Socket对象Socket client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp)IsConnet=true;//注意,此处是全局变量,将其设置为true//将方法写进线程中Thread thread=new Thread(() =>{while(IsConnet)//循环{try{client.Connect(IPAddress.Parse(Iptxt), Port);//尝试连接,失败则会跳去catchIsConnet=false;//成功连接后修改bool值为false,这样下一步循环就不再执行。break;//在此处加上break,成功就跳出循环,避免死循环}catch{client.Close();//先关闭/*使用新的客户端资源覆盖,上一个已经废弃。如果继续使用以前的资源进行连接,即使参数正确, 服务器全部打开也会无法连接*/client=new Socket(AddressFamily.InterNetwork,SocketType.Stream, ProtocolType.Tcp);Thread.Sleep(1000);//等待1s再去重连}}/*这里不一样就是放接收线程,在连接上后break出来,执行。因为需要带参数,所以要用到特别的ParameterizedThreadStart,然后开始线程。↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓*/Thread thread2 = new Thread(new ParameterizedThreadStart(ClientReceiveData));//接收线程方法thread2.IsBackground = true;//该值指示某个线程是否为后台线程。thread2.Start(client);//参数是用我们自建的Socket对象,就是上面的Socket client=new……});thread.IsBackground = true;//设置为后台线程,在程序退出时自己会自动释放thread.Start();//开始执行线程
}
复制代码

这样就是在连接后就会进入不断接收的子线程,接下来写接收程序的代码,与网络上的大同小异,只不过我们会稍作改动,在异常断开和正常退出时都去重新进行连接。Ip地址和端口号可以设置成全局变量,方便进行获取,代码如下:

 public void ClientReceiveData(object socket)//TCPClient消息的方法
{var ProxSocket = socket as Socket;//处理上一步传过来的Socket函数byte[] data = new byte[1024 * 1024];//接收消息的缓冲区while (!IsConnet)//同样循环中止的条件{int len = 0;//记录消息长度,以及判断是否连接try{//连接函数Receive会将数据放入data,从0开始放,之后返回数据长度。len = ProxSocket.Receive(data, 0, data.Length, SocketFlags.None);}catch (Exception){//异常退出ProxSocet.ShutDown(SocketShutdown.Both);//中止传输ProxSocet.Close();//关闭Connet(ip地址,端口号);//重新尝试去连接IsConnet=false;//注意,此处是全局变量,将其设置为false,防止循环return;//让方法结束,终结当前接收服务端数据的异步线程}if (len <= 0){//如果小于0,证明无连接,服务端正常退出ProxSocet.ShutDown(SocketShutdown.Both);//中止传输ProxSocet.Close();//关闭Connet(ip地址,端口号);//重新尝试去连接IsConnet=false;//注意,此处是全局变量,将其设置为false,防止循环return;//让方法结束,终结当前接收服务端数据的异步线程}//这里做你想要对消息做的处理//string str = Encoding.Default.GetString(data, 0, len);//二进制数组转换成字符串……}
}
复制代码

到这里就已经全部实现了!!接下来看看效果吧!!(以本人做的项目做例子)。

本次分享结束,有什么不足的地方,希望大家可以指出,或者不懂的可以留言问我,我们可以多交流!如果想实现图里动态刷新连接状态,可以看我上一篇文章C#LINQ实现动态刷新

C# Socket/TCPClient断线重连/不断重连的简单思路+代码,海量注释相关推荐

  1. guid会重复吗_知网查重会查重表格吗

    知网查重会查重表格吗?答案是肯定的.如果出现知网查重表格重复很高,那么我们一样是会进行避免查重的,通常表格在查重后会在报告中展示,如果出现重复会提示大家,我们只需要根据这个提示进行修改降低表格查重率即 ...

  2. 高性能服务器dyna软件重启动,LSDYNA重启动教程 ppt课件.ppt

    文档介绍: LSDYNA重启动教程第4-1章March7,2002Inventory#0016309-*LSDYNA重启动教程这一章主要介绍重启动.ANSYS/LS-DYNA中的三种重启动分析:sim ...

  3. 论文查重免费查重系统需要了解的常识

    现在很多人都有过写论文的经历. 大家 毕业时必须交毕业论文.工作之余, 大家 还要写一些学术论文.无论写哪种类型的论文,一般都需要对论文进行查重,因为只有符合查重标准的论文才是合格的论文.现在,网络上 ...

  4. mysql不可重复读和重复读_MySql隔离级别:RU / RC / RR / S + 脏读 / 不可重复读 / 幻读 / 可重复读...

    MySQL 事务 本文所说的 MySQL 事务都是指在 InnoDB 引擎下,MyISAM 引擎是不支持事务的. 数据库事务指的是一组数据操作,事务内的操作要么就是全部成功,要么就是全部失败,什么都不 ...

  5. 有备无患---使用密码重设盘重设Windows登录密码

    1.1.1 创建密码重设盘 创建密码重设盘,不论密码更改过多少次,如果忘记了计算机密码,则可以使用密码重设盘创建一个新密码.建议您在创建密码时创建密码重设盘,以便不会失去对文件和信息的访问权限. 1. ...

  6. 计算机专业查重及降重技巧

    作者:一一 链接:https://zhuanlan.zhihu.com/p/138670596 来源:知乎 著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. PS:本文只针对计算机 ...

  7. 称重管理系统地磅称重系统原来管理地磅这么简单?

      传统地磅称重的磅称量模式已经落后,现代社会科技高速发展,同时这个科技也在改变着我们的生活.称重体重也不例外.目前的称重系统拥有着非常成熟的技术,帮助企业挽回不少在称重环节出现的问题和损失.捷俊通成 ...

  8. 毕业论文查重的降重心得

    一.唠嗑 不知不觉已经要毕业了,总结分享一下最近几天的论文查重的降重过程~先上成果图(#^.^#) 第一次查重:o(╥﹏╥)o 目前结果:(* ̄︶ ̄)  二.技巧总结 经过了我抓耳挠腮的努力,终于把查 ...

  9. 【学习经验分享NO.15】本科硕士学位论文和学术论文查重及降重方法

    文章目录 前言 一.查重方法 1.查重指标的含义 2.查重方法 二.如何修改论文重复 三.常见问题答疑 总结 前言 学术小论文以及本科和硕士大论文在发表前需要进行降重处理,不然重复率过高会影响论文的发 ...

  10. 重保任务重,HW压力大,看多维融合重保解决方案为您解忧

    01 提高组织协同效率 解决应急响应.应急预案等关键安全活动缺乏信息化支撑的问题,导致组织协同效率低,包括内部组织.外部组织(安全外包服务提供商). 解决多厂商.多人协同,沟通成本高.执行效率低.速度 ...

最新文章

  1. android适配右到左布局注意事项
  2. Vue里标签嵌套限制问题解决------解析DOM模板时注意事项:
  3. android textview 文字居中_Android布局优化,看这3点就够了
  4. 课程设计个人报告——基于ARM实验箱的捕鱼游戏的设计与实现
  5. “刚毕业1年,做Python挣了60W!”网友:吹的不多..
  6. Kubernetes 部署 Ingress 控制器 Traefik v2.1
  7. UIViewAnimationOptions
  8. 大数据的价值与发展趋势
  9. python中的进程(二)
  10. Python2.7打包的exe文件反编译成py文件
  11. Docker系列之一:在线安装docker和下载镜像
  12. SpringMVC:生成Excel和PDF
  13. CMD如何直接运行文件
  14. JSCORE03(达)
  15. iPhone 13 真的要来了!苹果秋季发布会前瞻
  16. 【补档2017.12.28】我的2017-漫长的苦痛与渐入佳境的愤怒
  17. python/appium实现华为应用商城app界面上下滑动打开关闭通知栏等功能
  18. 窥尽大数据背后被遮掩起来的财富
  19. HCIP-H12-223练习题
  20. 请教税控开票数据aardio如何连接

热门文章

  1. DarkGDK的杯具体验
  2. ps6人脸识别液化工具在哪_ps液化工具在哪?(Photoshop基础教程:液化工具)
  3. 工业相机 - - 线阵相机
  4. Unity 加载读取PPT
  5. 好用的文献论文管理软件 EndNote X 9.3.3 Mac版
  6. plsql下载安装及基本使用
  7. 【线性系统理论】0.线性系统基本概念(1)
  8. 计算机网络 —— 冲突域和广播域
  9. 定位修改器服务器码,快手的定位修改器,快手定位到别的城市深度解析免费体验效果...
  10. 3章 RxJava操作符