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

修改SSDP部分实现

上级 5ee395e5
......@@ -134,7 +134,7 @@ namespace Mozi.HttpEmbedded
_socketDocker.TryAdd(so.Id, client);
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)
{
OnReceiveStart.BeginInvoke(this, new DataTransferArgs(), null, null);
......@@ -163,7 +163,7 @@ namespace Mozi.HttpEmbedded
so.ResetBuffer(iByteRead);
if (client.Available > 0){
//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{
InvokeAfterReceiveEnd(so, client);
}
......
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
namespace Mozi.HttpEmbedded
{
......@@ -10,13 +10,12 @@ namespace Mozi.HttpEmbedded
/// </summary>
class StateObject
{
public string Id {get;set;} //连接标识符
public string Id { get; set; } //连接标识符
public Socket WorkSocket = null;
public int RemotePort = 0;
public static int BufferSize = 1024;
public const int BufferSize = 1024;
public List<byte> Data=new List<byte>();
public byte[] Buffer = new byte[BufferSize*2];
public StringBuilder sb = new StringBuilder();
public string IP { get; set; }
//TODO 此处没有完整处理包体,会有多读取的冗余数据
......@@ -33,4 +32,11 @@ namespace Mozi.HttpEmbedded
Buffer = null;
}
}
/// <summary>
/// UDP通讯缓冲对象
/// </summary>
class UDPStateObject : StateObject
{
public EndPoint RemoteEndPoint { get; set; }
}
}
using System;
using System.Net;
using System.Net.Sockets;
namespace Mozi.HttpEmbedded
......@@ -12,53 +13,12 @@ namespace Mozi.HttpEmbedded
protected Socket _sc;
private EndPoint _remoteEndPoint=new IPEndPoint(IPAddress.Any, 0);
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>
......@@ -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>
/// <param name="iar"></param>
protected void CallbackReceive(IAsyncResult iar)
{
StateObject so = (StateObject)iar.AsyncState;
UDPStateObject so = (UDPStateObject)iar.AsyncState;
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)
{
//置空数据连接
so.ResetBuffer(iByteRead);
if (client.Available > 0)
{
//Thread.Sleep(10);
client.BeginReceive(so.Buffer, 0, StateObject.BufferSize, SocketFlags.None, CallbackReceive, so);
}
else
{
InvokeAfterReceiveEnd(so, client);
}
//Thread.Sleep(10);
_sc.BeginReceiveFrom(so.Buffer, 0, so.Buffer.Length, SocketFlags.None, ref remote, CallbackReceive, so);
}
else
{
InvokeAfterReceiveEnd(so, client);
InvokeAfterReceiveEnd(so, client, (IPEndPoint)remote);
}
}
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)
{
......@@ -149,11 +151,20 @@ namespace Mozi.HttpEmbedded
new DataTransferArgs()
{
Data = so.Data.ToArray(),
IP = so.IP,
Port = so.RemotePort,
IP = ((IPEndPoint)remote).Address.ToString(),
Port = ((IPEndPoint)remote).Port,
Socket = so.WorkSocket
}, 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 Mozi.HttpEmbedded;
......@@ -9,9 +10,11 @@ namespace Mozi.SSDP
/// </summary>
public class Service
{
//固定参数
private string BroadcastAddress = "239.255.255.250";
private int ProtocolPort = 1900;
//组播地址
public const string BroadcastAddress = "239.255.255.250";
//组播端口
public const int ProtocolPort = 1900;
private RequestMethod MSEARCH = new RequestMethod("M-SEARCH");
private RequestMethod NOTIFY = new RequestMethod("NOTIFY");
private const string QueryPath = "*";
......@@ -32,13 +35,42 @@ namespace Mozi.SSDP
/// 缓存时间
/// </summary>
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()
{
_socket = new UDPSocket();
_socket.AfterReceiveEnd += _socket_AfterReceiveEnd;
_remoteEP = new IPEndPoint(IPAddress.Parse(BroadcastAddress), ProtocolPort);
_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>
......@@ -81,18 +113,11 @@ namespace Mozi.SSDP
/// <summary>
/// 发送查询消息
/// </summary>
public void Discover()
public void Discover(DiscoverPackage dp)
{
HttpRequestU request = new HttpRequestU();
request.SetPath("*").SetMethod(MSEARCH);
TransformHeader headers = new TransformHeader();
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);
request.SetHeaders(dp.GetHeaders());
byte[] data = request.GetBuffer();
......@@ -111,19 +136,11 @@ namespace Mozi.SSDP
/// <summary>
/// 发送存在通知
/// </summary>
public void Notification()
public void Notification(NotificationPackage np)
{
HttpRequestU request = new HttpRequestU();
request.SetPath("*").SetMethod(NOTIFY);
TransformHeader headers = new TransformHeader();
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);
request.SetHeaders(np.GetHeaders());
byte[] data = request.GetBuffer();
_socket.SocketMain.SendTo(data, _remoteEP);
}
......@@ -137,16 +154,11 @@ namespace Mozi.SSDP
/// <summary>
/// 离线通知
/// </summary>
public void Leave()
public void Leave(ByebyePackage bp)
{
HttpRequestU request = new HttpRequestU();
request.SetPath("*").SetMethod(NOTIFY);
TransformHeader headers = new TransformHeader();
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);
request.SetHeaders(bp.GetHeaders());
byte[] data = request.GetBuffer();
_socket.SocketMain.SendTo(data, _remoteEP);
}
......@@ -176,7 +188,8 @@ namespace Mozi.SSDP
public void TimeoutCallback(object state)
{
Notification();
Discover(PackDefaultDiscover);
Notification(PackDefaultAlive);
}
}
......@@ -232,7 +245,7 @@ namespace Mozi.SSDP
public class ByebyePackage:AdvertisePackage
{
public string NT { get; set; }
public string NTS { get; set; }
//public string NTS { get; set; }
public string USN { get; set; }
public TransformHeader GetHeaders()
......@@ -258,5 +271,11 @@ namespace Mozi.SSDP
//USN: advertisement UUI
public string BroadcastAddress { 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.
先完成此消息的编辑!
想要评论请 注册