提交 87a403df 编写于 作者: JasonWcx's avatar JasonWcx

修改SSDP部分实现

上级 5ee395e5
...@@ -134,7 +134,7 @@ namespace Mozi.HttpEmbedded ...@@ -134,7 +134,7 @@ namespace Mozi.HttpEmbedded
_socketDocker.TryAdd(so.Id, client); _socketDocker.TryAdd(so.Id, client);
try try
{ {
client.BeginReceive(so.Buffer, 0, StateObject.BufferSize, SocketFlags.None, CallbackReceive, so); client.BeginReceive(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, CallbackReceive, so);
if (OnReceiveStart != null) if (OnReceiveStart != null)
{ {
OnReceiveStart.BeginInvoke(this, new DataTransferArgs(), null, null); OnReceiveStart.BeginInvoke(this, new DataTransferArgs(), null, null);
...@@ -163,7 +163,7 @@ namespace Mozi.HttpEmbedded ...@@ -163,7 +163,7 @@ namespace Mozi.HttpEmbedded
so.ResetBuffer(iByteRead); so.ResetBuffer(iByteRead);
if (client.Available > 0){ if (client.Available > 0){
//Thread.Sleep(10); //Thread.Sleep(10);
client.BeginReceive(so.Buffer, 0, StateObject.BufferSize, SocketFlags.None, CallbackReceive, so); client.BeginReceive(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, CallbackReceive, so);
}else{ }else{
InvokeAfterReceiveEnd(so, client); InvokeAfterReceiveEnd(so, client);
} }
......
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
using System.Text;
namespace Mozi.HttpEmbedded namespace Mozi.HttpEmbedded
{ {
...@@ -10,13 +10,12 @@ namespace Mozi.HttpEmbedded ...@@ -10,13 +10,12 @@ namespace Mozi.HttpEmbedded
/// </summary> /// </summary>
class StateObject class StateObject
{ {
public string Id {get;set;} //连接标识符 public string Id { get; set; } //连接标识符
public Socket WorkSocket = null; public Socket WorkSocket = null;
public int RemotePort = 0; public int RemotePort = 0;
public static int BufferSize = 1024; public const int BufferSize = 1024;
public List<byte> Data=new List<byte>(); public List<byte> Data=new List<byte>();
public byte[] Buffer = new byte[BufferSize*2]; public byte[] Buffer = new byte[BufferSize*2];
public StringBuilder sb = new StringBuilder();
public string IP { get; set; } public string IP { get; set; }
//TODO 此处没有完整处理包体,会有多读取的冗余数据 //TODO 此处没有完整处理包体,会有多读取的冗余数据
...@@ -33,4 +32,11 @@ namespace Mozi.HttpEmbedded ...@@ -33,4 +32,11 @@ namespace Mozi.HttpEmbedded
Buffer = null; Buffer = null;
} }
} }
/// <summary>
/// UDP通讯缓冲对象
/// </summary>
class UDPStateObject : StateObject
{
public EndPoint RemoteEndPoint { get; set; }
}
} }
using System; using System;
using System.Net;
using System.Net.Sockets; using System.Net.Sockets;
namespace Mozi.HttpEmbedded namespace Mozi.HttpEmbedded
...@@ -12,53 +13,12 @@ namespace Mozi.HttpEmbedded ...@@ -12,53 +13,12 @@ namespace Mozi.HttpEmbedded
protected Socket _sc; protected Socket _sc;
private EndPoint _remoteEndPoint=new IPEndPoint(IPAddress.Any, 0);
public UDPSocket() public UDPSocket()
{ {
} }
public new void StartServer(int port)
{
_iport = port;
if (_sc == null)
{
_sc = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
}
else
{
_sc.Close();
}
System.Net.IPEndPoint endpoint = new System.Net.IPEndPoint(System.Net.IPAddress.Any, _iport);
//允许端口复用
_sc.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_sc.Bind(endpoint);
//回调服务器启动事件
StateObject so = new StateObject()
{
//WorkSocket = client,
Id = Guid.NewGuid().ToString(),
//IP = ((System.Net.IPEndPoint)client.RemoteEndPoint).Address.ToString(),
//RemotePort = ((System.Net.IPEndPoint)client.RemoteEndPoint).Port,
};
if (OnServerStart != null)
{
OnServerStart(this, new ServerArgs() { StartTime = DateTime.Now, StopTime = DateTime.MinValue });
}
try
{
_sc.BeginReceive(so.Buffer, 0, StateObject.BufferSize, SocketFlags.None, CallbackReceive, so);
if (OnReceiveStart != null)
{
OnReceiveStart.BeginInvoke(this, new DataTransferArgs(),null,null);
}
}
catch (Exception ex)
{
var ex2 = ex;
}
}
/// <summary> /// <summary>
/// 服务器启动事件 /// 服务器启动事件
/// </summary> /// </summary>
...@@ -105,43 +65,85 @@ namespace Mozi.HttpEmbedded ...@@ -105,43 +65,85 @@ namespace Mozi.HttpEmbedded
} }
} }
public void StartServer(int port)
{
_iport = port;
if (_sc == null)
{
_sc = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, System.Net.Sockets.ProtocolType.Udp);
}
else
{
_sc.Close();
}
IPEndPoint endpoint = new IPEndPoint(IPAddress.Any, _iport);
//允许端口复用
_sc.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_sc.Bind(endpoint);
EndPoint _remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
//回调服务器启动事件
UDPStateObject so = new UDPStateObject()
{
WorkSocket = _sc,
Id = Guid.NewGuid().ToString(),
//IP = ((System.Net.IPEndPoint)client.RemoteEndPoint).Address.ToString(),
//RemotePort = ((System.Net.IPEndPoint)client.RemoteEndPoint).Port,
RemoteEndPoint= _remoteEndPoint
};
if (OnServerStart != null)
{
OnServerStart(this, new ServerArgs() { StartTime = DateTime.Now, StopTime = DateTime.MinValue });
}
try
{
_sc.BeginReceiveFrom(so.Buffer, 0, StateObject.BufferSize, SocketFlags.None, ref _remoteEndPoint, CallbackReceive, so);
if (OnReceiveStart != null)
{
OnReceiveStart.BeginInvoke(this, new DataTransferArgs(), null, null);
}
}
catch (Exception ex)
{
var ex2 = ex;
}
}
/// <summary> /// <summary>
/// 接收数据回调 /// 接收数据回调
/// </summary> /// </summary>
/// <param name="iar"></param> /// <param name="iar"></param>
protected void CallbackReceive(IAsyncResult iar) protected void CallbackReceive(IAsyncResult iar)
{ {
StateObject so = (StateObject)iar.AsyncState; UDPStateObject so = (UDPStateObject)iar.AsyncState;
Socket client = so.WorkSocket; Socket client = so.WorkSocket;
if (client.Connected)
{
int iByteRead = client.EndReceive(iar);
if (iByteRead > 0) EndPoint remote = (IPEndPoint)so.RemoteEndPoint;
int iByteRead = client.EndReceiveFrom(iar,ref remote);
//EndPoint remoteEndPoint = remote;
if (iByteRead > 0)
{
//置空数据连接
so.ResetBuffer(iByteRead);
if (client.Available > 0)
{ {
//置空数据连接 //Thread.Sleep(10);
so.ResetBuffer(iByteRead); _sc.BeginReceiveFrom(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, ref remote, CallbackReceive, so);
if (client.Available > 0)
{
//Thread.Sleep(10);
client.BeginReceive(so.Buffer, 0, StateObject.BufferSize, SocketFlags.None, CallbackReceive, so);
}
else
{
InvokeAfterReceiveEnd(so, client);
}
} }
else else
{ {
InvokeAfterReceiveEnd(so, client); InvokeAfterReceiveEnd(so, client, (IPEndPoint)remote);
} }
} }
else else
{ {
InvokeAfterReceiveEnd(so, client); InvokeAfterReceiveEnd(so, client, (IPEndPoint)remote);
} }
} }
private void InvokeAfterReceiveEnd(StateObject so, Socket client) private void InvokeAfterReceiveEnd(UDPStateObject so, Socket client,EndPoint remote)
{ {
if (AfterReceiveEnd != null) if (AfterReceiveEnd != null)
{ {
...@@ -149,11 +151,20 @@ namespace Mozi.HttpEmbedded ...@@ -149,11 +151,20 @@ namespace Mozi.HttpEmbedded
new DataTransferArgs() new DataTransferArgs()
{ {
Data = so.Data.ToArray(), Data = so.Data.ToArray(),
IP = so.IP, IP = ((IPEndPoint)remote).Address.ToString(),
Port = so.RemotePort, Port = ((IPEndPoint)remote).Port,
Socket = so.WorkSocket Socket = so.WorkSocket
}, null, null); }, null, null);
} }
UDPStateObject stateobject = new UDPStateObject()
{
WorkSocket = _sc,
Id = Guid.NewGuid().ToString(),
//IP = ((System.Net.IPEndPoint)client.RemoteEndPoint).Address.ToString(),
//RemotePort = ((System.Net.IPEndPoint)client.RemoteEndPoint).Port,
RemoteEndPoint = _remoteEndPoint
};
_sc.BeginReceiveFrom(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, ref _remoteEndPoint, CallbackReceive, so);
} }
} }
} }
using System.Net; using System;
using System.Net;
using System.Threading; using System.Threading;
using Mozi.HttpEmbedded; using Mozi.HttpEmbedded;
...@@ -9,9 +10,11 @@ namespace Mozi.SSDP ...@@ -9,9 +10,11 @@ namespace Mozi.SSDP
/// </summary> /// </summary>
public class Service public class Service
{ {
//固定参数 //组播地址
private string BroadcastAddress = "239.255.255.250"; public const string BroadcastAddress = "239.255.255.250";
private int ProtocolPort = 1900; //组播端口
public const int ProtocolPort = 1900;
private RequestMethod MSEARCH = new RequestMethod("M-SEARCH"); private RequestMethod MSEARCH = new RequestMethod("M-SEARCH");
private RequestMethod NOTIFY = new RequestMethod("NOTIFY"); private RequestMethod NOTIFY = new RequestMethod("NOTIFY");
private const string QueryPath = "*"; private const string QueryPath = "*";
...@@ -32,13 +35,42 @@ namespace Mozi.SSDP ...@@ -32,13 +35,42 @@ namespace Mozi.SSDP
/// 缓存时间 /// 缓存时间
/// </summary> /// </summary>
public int CacheTimeout = 3600; public int CacheTimeout = 3600;
/// <summary>
/// 默认包
/// </summary>
public DiscoverPackage PackDefaultDiscover = new DiscoverPackage()
{
MX=3,
ST= "upnp:rootdevice"
};
public NotificationPackage PackDefaultAlive = new NotificationPackage()
{
CacheTimeout = 3600,
Location = "",
Server = "",
NT="upnp:rootdevice",
USN=""
};
public ByebyePackage PackDefaultByebye = new ByebyePackage()
{
};
public Service() public Service()
{ {
_socket = new UDPSocket(); _socket = new UDPSocket();
_socket.AfterReceiveEnd += _socket_AfterReceiveEnd;
_remoteEP = new IPEndPoint(IPAddress.Parse(BroadcastAddress), ProtocolPort); _remoteEP = new IPEndPoint(IPAddress.Parse(BroadcastAddress), ProtocolPort);
_timer = new Timer(TimeoutCallback, null, Timeout.Infinite, Timeout.Infinite); _timer = new Timer(TimeoutCallback, null, Timeout.Infinite, Timeout.Infinite);
} }
private void _socket_AfterReceiveEnd(object sender, DataTransferArgs args)
{
Console.WriteLine("收到数据,{0}",args.IP);
Console.WriteLine(System.Text.Encoding.Default.GetString(args.Data));
}
/// <summary> /// <summary>
/// 激活 /// 激活
/// </summary> /// </summary>
...@@ -81,18 +113,11 @@ namespace Mozi.SSDP ...@@ -81,18 +113,11 @@ namespace Mozi.SSDP
/// <summary> /// <summary>
/// 发送查询消息 /// 发送查询消息
/// </summary> /// </summary>
public void Discover() public void Discover(DiscoverPackage dp)
{ {
HttpRequestU request = new HttpRequestU(); HttpRequestU request = new HttpRequestU();
request.SetPath("*").SetMethod(MSEARCH); request.SetPath("*").SetMethod(MSEARCH);
TransformHeader headers = new TransformHeader(); request.SetHeaders(dp.GetHeaders());
headers.Add(HeaderProperty.Host, $"{BroadcastAddress}:{ProtocolPort}");
headers.Add("S", "uuid:ijklmnop-7dec-11d0-a765-00a0c91e6bf6");
headers.Add("MAN", "\"ssdp:discover\"");
headers.Add("ST", "mozi-embedded:simplehost");
headers.Add("MX", "3");
request.SetHeaders(headers);
byte[] data = request.GetBuffer(); byte[] data = request.GetBuffer();
...@@ -111,19 +136,11 @@ namespace Mozi.SSDP ...@@ -111,19 +136,11 @@ namespace Mozi.SSDP
/// <summary> /// <summary>
/// 发送存在通知 /// 发送存在通知
/// </summary> /// </summary>
public void Notification() public void Notification(NotificationPackage np)
{ {
HttpRequestU request = new HttpRequestU(); HttpRequestU request = new HttpRequestU();
request.SetPath("*").SetMethod(NOTIFY); request.SetPath("*").SetMethod(NOTIFY);
TransformHeader headers = new TransformHeader(); request.SetHeaders(np.GetHeaders());
headers.Add(HeaderProperty.Host, $"{BroadcastAddress}:{ProtocolPort}");
headers.Add("SERVER", "mozi/embedded/simplehost");
headers.Add("NT","mozi-embedded:simplehost");
headers.Add("NTS", SSDPType.Alive.ToString());
headers.Add("USN", "mozi-embedded:simplehost");
headers.Add("LOCATION", "");
headers.Add(HeaderProperty.CacheControl, $"max-age= {CacheTimeout}");
request.SetHeaders(headers);
byte[] data = request.GetBuffer(); byte[] data = request.GetBuffer();
_socket.SocketMain.SendTo(data, _remoteEP); _socket.SocketMain.SendTo(data, _remoteEP);
} }
...@@ -137,16 +154,11 @@ namespace Mozi.SSDP ...@@ -137,16 +154,11 @@ namespace Mozi.SSDP
/// <summary> /// <summary>
/// 离线通知 /// 离线通知
/// </summary> /// </summary>
public void Leave() public void Leave(ByebyePackage bp)
{ {
HttpRequestU request = new HttpRequestU(); HttpRequestU request = new HttpRequestU();
request.SetPath("*").SetMethod(NOTIFY); request.SetPath("*").SetMethod(NOTIFY);
TransformHeader headers = new TransformHeader(); request.SetHeaders(bp.GetHeaders());
headers.Add(HeaderProperty.Host, $"{BroadcastAddress}:{ProtocolPort}");
headers.Add("NT", "mozi-embedded:simplehost");
headers.Add("NTS", SSDPType.Byebye.ToString());
headers.Add("USN", "mozi-embedded:simplehost");
request.SetHeaders(headers);
byte[] data = request.GetBuffer(); byte[] data = request.GetBuffer();
_socket.SocketMain.SendTo(data, _remoteEP); _socket.SocketMain.SendTo(data, _remoteEP);
} }
...@@ -176,7 +188,8 @@ namespace Mozi.SSDP ...@@ -176,7 +188,8 @@ namespace Mozi.SSDP
public void TimeoutCallback(object state) public void TimeoutCallback(object state)
{ {
Notification(); Discover(PackDefaultDiscover);
Notification(PackDefaultAlive);
} }
} }
...@@ -232,7 +245,7 @@ namespace Mozi.SSDP ...@@ -232,7 +245,7 @@ namespace Mozi.SSDP
public class ByebyePackage:AdvertisePackage public class ByebyePackage:AdvertisePackage
{ {
public string NT { get; set; } public string NT { get; set; }
public string NTS { get; set; } //public string NTS { get; set; }
public string USN { get; set; } public string USN { get; set; }
public TransformHeader GetHeaders() public TransformHeader GetHeaders()
...@@ -258,5 +271,11 @@ namespace Mozi.SSDP ...@@ -258,5 +271,11 @@ namespace Mozi.SSDP
//USN: advertisement UUI //USN: advertisement UUI
public string BroadcastAddress { get; set; } public string BroadcastAddress { get; set; }
public int ProtocolPort { get; set; } public int ProtocolPort { get; set; }
public AdvertisePackage()
{
BroadcastAddress = Service.BroadcastAddress;
ProtocolPort = Service.ProtocolPort;
}
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册