110,477
社区成员
发帖
与我相关
我的任务
分享
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Idyj.Net
{
/// <summary>
/// UDP广播定位服务,用于查找定位服务器在网络中的位置,
/// DetectClient 配置使用
/// </summary>
public class DetectServer:DisposableAndStartableBase
{
public string Name { get; set; }
public int Port { get; set; }
Socket sock;
public DetectServer(string name, int port)
{
Name = name;
Port = port;
}
private void Listen()
{
Thread.Sleep(100);
Debug.Assert(sock == null);
sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
try
{
IPEndPoint iep = new IPEndPoint(IPAddress.Any, Port);
sock.Bind(iep);
EndPoint ep = (EndPoint)iep;
NetDebuger.Trace(string.Format("Detect Server {1} listen port:{0}", Port,Name));
while (IsRunning)
{
byte[] data = new byte[1024];
int recv = 0;
try
{
recv = sock.ReceiveFrom(data, ref ep);
}
catch (SocketException ex)
{
if (ex.ErrorCode == 10054)
continue;
else
throw ex;
}
string request = Encoding.Default.GetString(data, 0, recv);
NetDebuger.Trace(string.Format("DS RX: {0} FROM: {1}", request, ep.ToString()));
if (request == "WHO IS " + Name)
{
string result = "I AM";
try
{
sock.SendTo(Encoding.Default.GetBytes(result), ep);
}
catch (SocketException ex)
{
if (ex.ErrorCode == 10054)
continue;
else
throw ex;
}
NetDebuger.Trace(string.Format("DS TX: {0} TO: {1}", result, ep.ToString()));
}
}
}
catch (NullReferenceException) { }
catch (SocketException) { }
catch (Exception ex)
{
NetDebuger.Error(ex.ToString());
if (IsRunning)
OnStart(); //重新启动,修复自己
}
finally
{
CloseSocket();
}
}
protected override void OnStart()
{
//Start listen thread
Task.Factory.StartNew(() => { Listen(); });
}
protected override void OnStop()
{
//Close socket would be exit the listen thread
CloseSocket();
}
protected override void Free(bool dispodedByUser)
{
if (dispodedByUser)
{
CloseSocket();
}
base.Free(dispodedByUser);
}
private void CloseSocket()
{
if (sock != null)
{
lock (sock)
{
if (sock != null)
{
sock.Close();
sock = null;
}
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Diagnostics;
using System.ComponentModel;
namespace Idyj.Net
{
/// <summary>
/// UDP定位客户端
/// </summary>
public class DetectClient:DisposableBase
{
public string ServerName { get; private set; }
public int ServerPort { get; private set; }
public int ServerCount { get; set; }
public int Timeout { get; set; }
public List<string> Servers { get; private set; }
public DetectClient(string serverName, int serverPort)
{
ServerName = serverName;
ServerPort = serverPort;
ServerCount = 1;
Timeout = 3000;
Servers = new List<string>();
}
private Socket sock;
IPEndPoint iep;
AsyncHelper async = new AsyncHelper();
public delegate void DetectEventHandler();
public event AsyncCompletedEventHandler DetectCompleted;
private void DetectCompletionMethord(Object state)
{
IAsyncResult iar = state as IAsyncResult;
AsyncCompletedEventArgs e = async.CreateAsyncCompletedEventArgs(this);
AsyncCompletedEventHandler tmp = (AsyncCompletedEventHandler)(iar.AsyncState);
if (tmp != null)
{
tmp(this, e);
}
async.EndAsyncOperation();
}
public void CancelDetect()
{
async.CancelAsyncOperation();
}
public void DetectAsync()
{
async.BeginAsyncOperation();
DetectEventHandler detectDelegate = new DetectEventHandler(Detect);
detectDelegate.BeginInvoke(DetectCompletionMethord, DetectCompleted);
}
public void Detect()
{
Thread t = new Thread(new ThreadStart(DetectServer));
t.Start();
async.WaitAsyncResult(Timeout);
CloseSocket();
}
private void DetectServer()
{
try
{
if (sock != null)
{
CloseSocket();
}
this.Servers.Clear();
sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
iep = new IPEndPoint(IPAddress.Broadcast, ServerPort);
byte[] req = Encoding.Default.GetBytes("WHO IS " + ServerName);
sock.SendTo(req, iep);
NetDebuger.Trace("TX " + "WHO IS " + ServerName);
for (int i = 0; i < ServerCount; i++)
{
RECV_DATA:
byte[] data = new byte[1024];
EndPoint ep = (EndPoint)iep;
int recv = sock.ReceiveFrom(data, ref ep);
if (Encoding.Default.GetString(data, 0, recv) == "I AM")
{
Servers.Add(ep.ToString().Split(':')[0]);
}
else
{
goto RECV_DATA;
}
}
async.EndAsyncOperation();
}
//User cancel the listen data, exit the thread for using exception
catch (NullReferenceException) { }
catch (SocketException) { }
catch (Exception e)
{
async.EndAsyncOperationWithError(e);
}
finally
{
CloseSocket();
}
}
protected override void Free(bool dispodedByUser)
{
if (dispodedByUser)
{
CloseSocket();
}
base.Free(dispodedByUser);
}
private void CloseSocket()
{
if (sock != null)
{
lock (sock)
{
if (sock != null)
{
sock.Close();
sock = null;
}
}
}
}
}
}