using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace LAN
{
/// <summary>
/// UdpSocket使用方法:
/// 1:首先实例化UdpSocket(本机ip,本机端口) UdpSocket udpSocket = new UdpSocket(xx,xx);
/// 2:然后执行初始化 udpSocket.Init(Rev3232)。Rev3232为需要用到的进程方法名
/// 3:注意例程带//********//位置的操作。
/// 4:关闭时先执行_threadFlag3232 = false;然后执行udpSocket.Close();
/// 例程:
//UdpSocket udpSocket = new UdpSocket(xx,xx);
//_threadFlag3232 = true;
//udpSocket.Init(Rev3232);
//
// private void Rev3232()
//{
// //接收数据处理线程
// string msg = "";
// MyInvoke_3232 myI = new MyInvoke_3232(UpdateMsg_3232);
// while (_threadFlag3232)
// {
// if (udpSocket.RevQueue.Count == 0)//********//
// {
// Thread.Sleep(1);
// continue;
// }
// else
// {
// byte[] data;
// lock (udpSocket.Lock)//********//
// {
// _test2 = udpSocket.RevQueue.Count;//********//
// data = udpSocket.RevQueue.Dequeue();//********//
// }
// int rlen = data.Length;
// int[] intDataBuff = new int[rlen / 4];
// for (int i = 0; i < rlen / 4; i++)
// {
// intDataBuff[i] = BitConverter.ToInt32(data, i * 4);
// }
// if ((intDataBuff[0] == 0x48449880) && ((intDataBuff[1] == 0x21111996) || (intDataBuff[1] == 0x21111997)))
// {
// _revFlag = 1;
// }
// BeginInvoke(myI, new object[] { data });
// }
// }
//}
/// </summary>
public class UdpSocket
{
#region 私有变量
private EndPoint _sendIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
private readonly byte[] _revDataBuffBytes = new byte[2048];
private readonly AsyncCallback ReceiveCallback;
private bool _closeFlag;
#endregion
#region 公有变量
public Queue<byte[]> RevQueue = new Queue<byte[]>();
public Socket MySocket;
public readonly object Lock = new object();
public string MyIpAddr ;
public int MyPortNum;
public Thread RevThread;
public delegate void InvokeFun();
#endregion
/// <summary>
/// 实例化UdpSocket
/// </summary>
/// <param name="myIpAddr">本机IP地址</param>
/// <param name="myPortNum">本机需要打开的端口</param>
public UdpSocket(string myIpAddr, int myPortNum)
{
ReceiveCallback = new AsyncCallback(OnDataReceived);
MySocket = null;
MyIpAddr = myIpAddr;
MyPortNum = myPortNum;
}
/// <summary>
/// 初始化
/// </summary>
/// <param name="revFun">线程功能函数(不带参数)</param>
/// <returns>返回初始化成功的Socket</returns>
public Socket Init(InvokeFun revFun)
{
try
{
IPAddress lip;
IPAddress.TryParse(MyIpAddr, out lip);
//初始化socket,定义网络类型,数据连接类型与网络协议UDP
MySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
MySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
IPEndPoint ipLocalPoint = new IPEndPoint(lip, MyPortNum);
//绑定网络地址
MySocket.Bind(ipLocalPoint);
MySocket.ReceiveBufferSize = 64 * 1024;
_closeFlag = true;
RevThread = new Thread(new ThreadStart(revFun));
RevThread.Start();
MySocket.BeginReceive(_revDataBuffBytes, 0, _revDataBuffBytes.Length, SocketFlags.None, ReceiveCallback, MySocket);
return MySocket;
}
catch
{
return null;
}
}
/// <summary>
/// 初始化
/// </summary>
/// <returns>返回初始化成功的Socket</returns>
public Socket Init()
{
try
{
IPAddress lip;
IPAddress.TryParse(MyIpAddr, out lip);
//初始化socket,定义网络类型,数据连接类型与网络协议UDP
MySocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
MySocket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
IPEndPoint ipLocalPoint = new IPEndPoint(lip, MyPortNum);
//绑定网络地址
MySocket.Bind(ipLocalPoint);
MySocket.ReceiveBufferSize = 64 * 1024;
_closeFlag = true;
MySocket.BeginReceive(_revDataBuffBytes, 0, _revDataBuffBytes.Length, SocketFlags.None, ReceiveCallback, MySocket);
return MySocket;
}
catch
{
return null;
}
}
private void OnDataReceived(IAsyncResult ar)
{
try
{
if (_closeFlag == true)
{
Socket udpSocket = ar.AsyncState as Socket;
int bytesRecved = udpSocket.EndReceive(ar);
byte[] data = new byte[bytesRecved];
Array.Copy(_revDataBuffBytes, data, bytesRecved);
lock (Lock)
{
RevQueue.Enqueue(data);
}
MySocket.BeginReceive(_revDataBuffBytes, 0, _revDataBuffBytes.Length, SocketFlags.None, ReceiveCallback, MySocket);
}
}
catch
{
}
}
public void Close()
{
_closeFlag = false;
if (RevThread != null)
{
RevThread.Abort();
}
MySocket.Close();
RevQueue.Clear();
}
}
}