应用场景:当每一台终端开启程序后发出消息,其他终端必须收到消息然后处理

思路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广播通信加强广播通信的稳定性的更多相关文章

  1. FTP和TCP、UDP

    应用:TFTP客户端 1. TFTP协议介绍 TFTP(Trivial File Transfer Protocol,简单文件传输协议) 是TCP/IP协议族中的一个用来在客户端与服务器之间进行简单文 ...

  2. 基于TCP与UDP协议的socket通信

    基于TCP与UDP协议的socket通信 C/S架构与初识socket 在开始socket介绍之前,得先知道一个Client端/服务端架构,也就是 C/S 架构,互联网中处处充满了 C/S 架构(Cl ...

  3. 以QQ举例 说明计算机网络中的一些概念区别(TCP与UDP,广播与单播)

    QQ 中的 广播与单播 今天简单地学习了一下 广播和多播(组播) 的知识.关于 单播和多播 的概念,可以用 QQ 中的一些例子来解释. 单播,就像 两个人聊QQ 一样,信息的接收和传递只在两个节点之间 ...

  4. 计算机网络通信、线程、tcp、udp通信及信号量等读书笔记

    一.计算机网络 1.什么是计算机网络:把分布在不同地理位置的计算机与专门的网络设备用通信线路互相连成一个规模大.功能强的系统,从而使众多计算机可以方便地互相传递信息.共享软件.硬件.数据信息等.简单来 ...

  5. TCP、UDP、Socket 通信(原)

    说明:本随笔主要演示自己给自己发送消息例子,分别使用了TCP协议.UDP协议以及socket套接字通信.使用socket套接字了模拟TCP.UDP通信实现原理.其中有些源码都来自<C#高级编程 ...

  6. 实现TCP、UDP相互通信及应用

    实验名称  Socket编程综合实验(1) 一.实验目的: 1.理解进程通信的原理及通信过程 2.掌握基于TCP和UDP的工作原理 3.掌握基本的Socket网络编程原理及方法 二.实验内容 1.掌握 ...

  7. 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP

    [源码下载] 重新想象 Windows 8 Store Apps (62) - 通信: Socket TCP, Socket UDP 作者:webabcd 介绍重新想象 Windows 8 Store ...

  8. 高性能 TCP &amp; UDP 通信框架 HP-Socket v3.2.3 正式宣布

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包括服务端组件.client组件和 Agent 组件.广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#. ...

  9. 高性能 TCP &amp; UDP 通信框架 HP-Socket v3.2.2 正式公布

    HP-Socket 是一套通用的高性能 TCP/UDP 通信框架,包括服务端组件.client组件和 Agent 组件,广泛适用于各种不同应用场景的 TCP/UDP 通信系统,提供 C/C++.C#. ...

随机推荐

  1. 从 Socket 编程谈谈 IO 模型(三)

    快过年啦,估计很多朋友已在摸鱼的路上.而我为了兄弟们年后的追逐,却在苦苦寻觅.规划,导致文章更新晚了些,各位猿粉谅解. 上期分享,我们结合新春送祝福的场景,通过一坨坨的代码让 BIO.NIO 编程过程 ...

  2. 记录一次简单的springboot发送邮件功能

    场景:经常在我们系统中有通过邮件功能找回密码,或者发送生日祝福等功能,今天记录下springboot发送邮件的简单功能 1.引入maven <!-- 邮件开发--><dependen ...

  3. 个人hexo博客(静态,无后台)搭建

    博客搭建 1.工具安装 安装Node.js,其中包含Node.js和npm(包管理器) 利用npm安装cnpm(淘宝的npm,速度在国内更快) npm install -g cnpm --regist ...

  4. js中的位置属性

    原生js中位置信息 clientLeft,clientTop:表示内容区域的左上角相对于整个元素左上角的位置(包括边框),实测,clientLeft=左侧边框的宽度,clientTop=顶部边框的宽度 ...

  5. Linux基础:Day04

    进程管理1.操作系统基础 调用:kernel通过给应用程序提供system call方式来提供硬件资源:  注意:这个应用程序也包括库文件:  库文件是运行在ring 0上的一段程序代码,不对客户直接 ...

  6. MTK Android 耳机线控的实现方法

    android 耳机线控的实现方法 keycodeonkeydownkeyevent 耳机线控的功能 耳机线控是一种很好用,并且能提升用户体验的功能.可以用来实现一些常用和基本的功能.比如:实现音乐播 ...

  7. Linux网络安全篇,进入SELinux的世界(四)

    SELinux的策略与规则管理set 1.安装SELInux工具 yum install setools-console 2.基本的命令 seinfo [-Atrub] -A ===> 列出SE ...

  8. javascript入门 之 bind()

    <!DOCTYPE html> <HTML> <HEAD> <meta http-equiv="content-type" content ...

  9. c++ 启发式搜索解决八数码问题

    本文对八数码问题 启发式搜索 (C++)做了一点点修改 //fn=gn+hn #include<iostream> #include<queue> #include<st ...

  10. 这本最适合夯实基础的经典 Java 书籍,可能80% 的 Java 程序员没有认真看过!

    公众号[程序员书单]出品,转载请注明出处 作者:黄小斜 今天要给大家带来的一本书,是大名鼎鼎的head first系列丛书的一本<head first Java>相信很多学习Java的朋友 ...