.net 使用TCP模拟UDP广播通信加强广播通信的稳定性
应用场景:当每一台终端开启程序后发出消息,其他终端必须收到消息然后处理
思路1:使用UDP广播。 缺点:UDP广播信号不稳定,无法确定每一台机器能接收到信号
思路2:将一台主机作为服务器,使用TCP协议用此服务器转发消息 缺点:需要另外开发服务端,且其他端必须配置IP,灵活性差。
本文讲述的是第三个思路
思路3:开启程序后先设法发现其他终端,每个终端开启一个TCP服务socket,需要发广播的机器开启多个TCP客户端连接其他终端的TCP服务端稳定通信,至于如何使所有终端能相互发现 本文使用的是用UDP广播信号暴露自己,另外还可使用局域网遍历端口等方式。
代码:
发广播暴露自己:
- Thread BroadcastTh;
- /// <summary>
- /// 发起广播使其他终端能检测到
- /// </summary>
- public void StartBroadCast()
- {
- try
- {
- if (BroadcastTh != null)
- {
- BroadcastTh.Abort();
- }
- BroadcastTh = new Thread(() =>
- {
- int i = ;
- while (i < )
- {
- i++;
- Thread.Sleep();
- SendBroadcast("ConnectMe", );
- }
- });
- BroadcastTh.IsBackground = true;
- BroadcastTh.Start();
- }
- catch (Exception ex)
- {
- SimpleLog.WriteLog(ex.ToString());
- }
- }
这边是每隔500毫秒连续发200次,也可以无限发送广播,本人有强迫症不喜欢 while(true),况且如果开启的机器太多机器发送的广播量太多,相互监听的就越多,影响通信流量。
- public void SendBroadcast(string msg, int port)
- {
- try
- {
- Socket recieveSock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- IPEndPoint iep = new IPEndPoint(IPAddress.Broadcast, port);
- byte[] data = Encoding.UTF8.GetBytes(msg);
- recieveSock.SetSocketOption(SocketOptionLevel.Socket,
- SocketOptionName.Broadcast, );
- recieveSock.SendTo(data, iep);
- }
- catch (Exception ex)
- {
- SimpleLog.WriteLog(ex.ToString());
- }
- }
接收广播信号,将其他终端地址添加到本地列表
- Socket BroadcastRecievesocket;
- /// <summary>
- /// 监听广播信号
- /// </summary>
- public void ReceiveBroadcast()
- {
- Thread receiveThread = new Thread(() =>
- {
- try
- {
- BroadcastRecievesocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- IPEndPoint iep = new IPEndPoint(IPAddress.Any, );
- EndPoint ep = (EndPoint)iep;
- BroadcastRecievesocket.Bind(iep);
- while (true)
- {
- try
- {
- byte[] buffer = new byte[];
- BroadcastRecievesocket.ReceiveFrom(buffer, ref ep);
- string msg = Encoding.UTF8.GetString(buffer);
- string endaddress = ep.ToString().Split(':')[];
- if (msg.Replace("\0","") == "ConnectMe")
- {
- if (!SocketList.ContainsKey(endaddress) && endaddress != localhost)
- {
- StartBroadCast();
- SocketList.Add(endaddress, null);
- }
- }
- else if (msg.Replace("\0", "") == "Offline")
- {
- if (SocketList.ContainsKey(endaddress))
- SocketList.Remove(endaddress);
- }
- // MessageBox.Show(time);
- }
- catch (Exception ex)
- {
- SimpleLog.WriteLog(ex.ToString());
- }
- }
- }
- catch (Exception)
- {
- BroadcastRecievesocket.Dispose();
- ReceiveBroadcast();
- }
- })
- {
- IsBackground = true
- };
- receiveThread.Start();
- }
开启tcp服务端
- #region TCP服务端
- Socket socketWatch;
- /// <summary>
- /// 启动TCP服务端socket
- /// </summary>
- private void StartTCPServer()
- {
- try
- {
- socketWatch = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
- //点击开始监听时 在服务端创建一个负责监听IP和端口号的Socket
- IPAddress ip = IPAddress.Any; //创建对象端口
- IPEndPoint point = new IPEndPoint(ip, );
- socketWatch.Bind(point);//绑定端口号
- socketWatch.Listen();//设置监听
- Thread thread = new Thread(Listen);
- thread.IsBackground = true;
- thread.Start(socketWatch);
- }
- catch (Exception ex)
- {
- SimpleLog.WriteLog(ex.ToString());
- }
- }
- private void Listen(object o)
- {
- try
- {
- Socket socketWatch = o as Socket;
- while (true)
- {
- Socket socketSend = socketWatch.Accept();//等待接收客户端连接
- Thread r_thread = new Thread(Received);
- r_thread.IsBackground = true;
- r_thread.Start(socketSend);
- }
- }
- catch (Exception ex)
- {
- SimpleLog.WriteLog(ex.ToString());
- }
- }
- /// <summary>
- /// 服务器端不停的接收客户端发来的消息
- /// </summary>
- /// <param name="o"></param>
- void Received(object o)
- {
- try
- {
- Socket socketSend = o as Socket;
- while (true)
- {
- //客户端连接服务器成功后,服务器接收客户端发送的消息
- byte[] buffer = new byte[];
- //实际接收到的有效字节数
- int len = socketSend.Receive(buffer);
- if (len == )
- {
- break;
- }
- string str = Encoding.UTF8.GetString(buffer, , len);
- HandleTime(str);
- }
- }
- catch (Exception ex)
- {
- SimpleLog.WriteLog(ex.ToString());
- }
- }
- #endregion
发消息时开启多个TCP客户端连接列表中IP地址对应的服务端
- Thread broadcast = new Thread(() =>
- {
- string[] keyStr = SocketList.Keys.ToArray();
- for (int i = keyStr.Length - ; i >= ; i--)
- {
- try
- {
- Socket socketitem;
- if (SocketList[keyStr[i]] != null)
- {
- socketitem = SocketList[keyStr[i]];
- }
- else
- {
- socketitem = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); ;
- IPAddress ip = IPAddress.Parse(keyStr[i]);
- IPEndPoint point = new IPEndPoint(ip, );
- socketitem.Connect(point);
- }
- DateTime dateTime = DateTime.Now;
- string minisec = (Convert.ToDecimal(dateTime.Millisecond) / ).ToString("0.0000");
- socketitem.Send(Encoding.UTF8.GetBytes(dateTime.ToLongTimeString() + minisec.Substring(, minisec.Length - )));
- }
- catch (Exception ex)
- {
- SimpleLog.WriteLog(ex.ToString());
- SocketList.Remove(keyStr[i]);
- }
- }
- });
- broadcast.IsBackground = true;
- broadcast.Start();
以上代码是部分代码。仅供参考
总结:然并卵
.net 使用TCP模拟UDP广播通信加强广播通信的稳定性的更多相关文章
- FTP和TCP、UDP
应用:TFTP客户端 1. TFTP协议介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议) 是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文 ...
- 基于TCP与UDP协议的socket通信
基于TCP与UDP协议的socket通信 C/S架构与初识socket 在开始socket介绍之前,得先知道一个Client端/服务端架构,也就是 C/S 架构,互联网中处处充满了 C/S 架构(Cl ...
- 以QQ举例 说明计算机网络中的一些概念区别(TCP与UDP,广播与单播)
QQ 中的 广播与单播 今天简单地学习了一下 广播和多播(组播) 的知识.关于 单播和多播 的概念,可以用 QQ 中的一些例子来解释. 单播,就像 两个人聊QQ 一样,信息的接收和传递只在两个节点之间 ...
- 计算机网络通信、线程、tcp、udp通信及信号量等读书笔记
一.计算机网络 1.什么是计算机网络:把分布在不同地理位置的计算机与专门的网络设备用通信线路互相连成一个规模大.功能强的系统,从而使众多计算机可以方便地互相传递信息.共享软件.硬件.数据信息等.简单来 ...
- TCP、UDP、Socket 通信(原)
说明:本随笔主要演示自己给自己发送消息例子,分别使用了TCP协议.UDP协议以及socket套接字通信.使用socket套接字了模拟TCP.UDP通信实现原理.其中有些源码都来自<C#高级编程 ...
- 实现TCP、UDP相互通信及应用
实验名称 Socket编程综合实验(1) 一.实验目的: 1.理解进程通信的原理及通信过程 2.掌握基于TCP和UDP的工作原理 3.掌握基本的Socket网络编程原理及方法 二.实验内容 1.掌握 ...
- 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP
[源码下载] 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP 作者:webabcd 介绍重新想象 Windows 8 Store ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.2.3 正式宣布
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包括服务端组件.client组件和 Agent 组件.广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#. ...
- 高性能 TCP & UDP 通信框架 HP-Socket v3.2.2 正式公布
HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包括服务端组件.client组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#. ...
随机推荐
- 想读Spring源码?先从这篇「 极简教程」开始吧...
为什么要阅读源码?这是一个有趣的问题,类似的问题还有,为什么要看书?为什么要爬山? 这也是一个哲学问题,我想每个人都有不同的答案,下面我是对阅读源码好处的一些思考. (PS:也欢迎你在评论区留言补充) ...
- ERROR:TypeError: Cannot read property 'upgrade' of undefined
- canvas 悬浮效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- PTA数据结构与算法题目集(中文) 7-34
PTA数据结构与算法题目集(中文) 7-34 7-34 任务调度的合理性 (25 分) 假定一个工程项目由一组子任务构成,子任务之间有的可以并行执行,有的必须在完成了其它一些子任务后才能执行.“ ...
- .Net微服务实践(四)[网关]:Ocelot限流熔断、缓存以及负载均衡
目录 限流 熔断 缓存 Header转化 HTTP方法转换 负载均衡 注入/重写中间件 后台管理 最后 在上篇.Net微服务实践(三)[网关]:Ocelot配置路由和请求聚合中我们介绍了Ocelot的 ...
- go 闭包函数
一.什么是闭包函数? 二.匿名函数可以被赋值给变量并作为值使用: package main import "fmt" func main(){ f() } func f(){ fo ...
- 28.5 Integer-- int的包装类
* 由于基本数据类型只能做一些简单的操作和运算,所以Java为我们封装了基本数据类型,为每种基本数据类型提供了包装类 * 包装类就是封装了基本数据类型的类,为我们提供了更多复杂的方法和一些变量 * * ...
- Html5移动端弹幕动画实现示例代码
已知20条内容要有弹幕效果,分成三层,速度随机. 先来看看效果: 所以这里不考虑填写生成的.只是一个展现的效果. 如果要看填写生成的,请不要浪费Time 思路 把单个内容编辑好,计算自身宽度,确定初始 ...
- 极验反爬虫防护分析之slide验证方式下图片的处理及滑动轨迹的生成思路
本文要分享的内容是去年为了抢鞋而分析 极验(GeeTest)反爬虫防护的笔记,由于篇幅较长(为了多混点CB)我会按照我的分析顺序,分成如下四个主题与大家分享: 极验反爬虫防护分析之交互流程分析 极验反 ...
- 串匹配问题 (KMP算法) 详解
串这个概念对于我们学到现在的水平来说应该是经历颇丰了,因为在C语言中我们所用到的"串"知识是在字符串那里,有了这个概念,我们再去学习串就相对而言轻松多了. 那么,现在来介绍一下字符 ...