Plane.Sdk3/PlaneGcsSdk_Shared/Communication/TcpServerConnectionManager.cs
2020-09-20 11:43:27 +08:00

106 lines
3.1 KiB
C#

#if !NETFX_CORE
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace Plane.Communication
{
/// <summary>
/// 监听远程主机的 TCP 连接请求并创建 <see cref="TcpServerConnection"/> 实例与它通信。
/// </summary>
public class TcpServerConnectionManager : ExceptionThrownEventSource, IDisposable
{
private const int TCP_LOCAL_PORT = 5250;
private static TcpServerConnectionManager _Instance = new TcpServerConnectionManager();
private bool _disposed;
private bool _isListening;
// TODO: 王海, 20150909, 从配置文件中获取要监听的 IP 地址和端口号。
private TcpListener _listener;
private bool _shouldListen;
private TcpServerConnectionManager()
{
}
public event EventHandler<ConnectionEstablishedEventArgs> ConnectionEstablished;
public static TcpServerConnectionManager Instance { get { return _Instance; } }
public void Dispose()
{
if (_disposed)
{
return;
}
StopListening();
_disposed = true;
}
public bool StartListening()
{
if (_disposed)
{
throw new ObjectDisposedException(nameof(TcpServerConnectionManager));
}
if (_shouldListen && _isListening) return true;
var address = Dns.GetHostAddresses(Dns.GetHostName()).FirstOrDefault(addr => addr.AddressFamily == AddressFamily.InterNetwork && addr.GetAddressBytes()[0] == 192);
if (address == null) return false;
_listener = new TcpListener(address, TCP_LOCAL_PORT);
try
{
_listener.Start();
}
catch (Exception ex)
{
// RaiseExceptionThrown(ex);
return false;
}
_shouldListen = true;
Task.Factory.StartNew(async () =>
{
while (_isListening)
{
await Task.Delay(5);
}
_isListening = true;
while (_shouldListen)
{
try
{
var tcpClient = await _listener.AcceptTcpClientAsync();
if (_shouldListen)
{
ConnectionEstablished?.Invoke(
this,
new ConnectionEstablishedEventArgs(new TcpServerConnection(tcpClient), (tcpClient.Client.RemoteEndPoint as IPEndPoint).Address.ToString())
);
}
}
catch (Exception ex)
{
RaiseExceptionThrown(ex);
}
}
_isListening = false;
});
return true;
}
public void StopListening()
{
_shouldListen = false;
_listener?.Stop();
}
}
}
#endif