blob: c8453fb253472329d727b1da341b4be5365c2228 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Tango.Logging;
namespace Tango.Transport.Servers
{
/// <summary>
/// Represents a TCP/IP listener wrapper.
/// </summary>
public class TcpServer
{
private TaskScheduler scheduler;
private LogManager LogManager = LogManager.Default;
/// <summary>
/// The TcpListener that is encapsulated behind this Server instance.
/// </summary>
public TcpListener Listener { get; set; }
/// <summary>
/// The Port that is used to listen to incoming connections.
/// </summary>
public int Port { get; set; }
/// <summary>
/// Returns true if the Server instance is running.
/// </summary>
public bool IsStarted { get; private set; }
#region Events
public event EventHandler<ClientConnectedEventArgs> ClientConnected;
#endregion
#region Constructors
/// <summary>
/// Initializes a new Server instance.
/// </summary>
/// <param name="port">The port number that is used to listen for incoming connections.</param>
public TcpServer(int port)
{
Port = port;
}
#endregion
#region Public Methods
/// <summary>
/// Start Listening for incoming connections.
/// </summary>
public void Start()
{
if (!IsStarted)
{
if (scheduler == null)
{
scheduler = TaskScheduler.FromCurrentSynchronizationContext();
}
Listener = new TcpListener(System.Net.IPAddress.Any, Port);
Listener.Start();
IsStarted = true;
LogManager.Log("Server Started!");
WaitForConnection();
}
}
/// <summary>
/// Stop listening for incoming connections.
/// </summary>
public void Stop()
{
if (IsStarted)
{
Listener.Stop();
IsStarted = false;
LogManager.Log("Server Stopped!");
}
}
#endregion
#region Incoming Connections Methods
private void WaitForConnection()
{
Listener.BeginAcceptTcpClient(new AsyncCallback(ConnectionHandler), null);
}
private void ConnectionHandler(IAsyncResult ar)
{
if (IsStarted)
{
try
{
OnClientConnected(Listener.EndAcceptTcpClient(ar));
WaitForConnection();
}
#pragma warning disable CS0168 // Variable is declared but never used
catch (ObjectDisposedException ex)
#pragma warning restore CS0168 // Variable is declared but never used
{
//Ignore..
}
}
}
#endregion
#region Virtual Methods
protected virtual void OnClientConnected(TcpClient socket)
{
LogManager.Log("New client connected.");
Task.Factory.StartNew(() =>
{
ClientConnected?.Invoke(this, new ClientConnectedEventArgs(socket));
},CancellationToken.None,TaskCreationOptions.None,scheduler);
}
#endregion
}
}
|