annotate Net/TCPServer.cs @ 15:7c1808f28e05

HTTP: Correctly interpret tar file path names in HTTPUnTarchiveProvider
author Ivo Smits <Ivo@UCIS.nl>
date Fri, 15 Mar 2013 00:02:58 +0100
parents 3ab940a0c7a0
children 4ba4fd48e1da
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 ???using System;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
2 using System.Net;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
3 using System.Net.Sockets;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4 using System.Threading;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
5 using System.Collections.Generic;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
6
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
7 namespace UCIS.Net {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8 public class TCPServer {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9 public class ModuleCollection : Dictionary<byte, IModule> {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 public void Add(char Key, IModule Value) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
11 base.Add((byte)Key, Value);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
12 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
13 public void Remove(char Key) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
14 base.Remove((byte)Key);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
15 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
16 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
17
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
18 public class ClientAcceptedEventArgs : EventArgs {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
19 private TCPStream _client;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
20 internal ClientAcceptedEventArgs(TCPStream client) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
21 _client = client;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
22 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
23 public TCPStream Client { get { return _client; } }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
24 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
25
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
26 public event EventHandler<ClientAcceptedEventArgs> ClientAccepted;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
27
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
28 private Socket _Listener;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
29 private UCIS.ThreadPool _ThreadPool;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
30 private NetworkConnectionList _Clients = new NetworkConnectionList();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
31 private ModuleCollection _Modules = new ModuleCollection();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
32 private IModule _CatchAllModule = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
33 private Int32 _ThrottleCounter;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
34 private Int32 _ThrottleBurst = 10;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
35 private Int32 _ThrottleRate = 0;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
36 private Timer _ThrottleTimer = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
37
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
38 public TCPServer() {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
39 _ThreadPool = UCIS.ThreadPool.DefaultPool;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
40 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
41
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
42 public NetworkConnectionList Clients {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
43 get { return _Clients; }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
44 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
45
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
46 public ModuleCollection Modules {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
47 get { return _Modules; }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
48 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
49
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
50 public IModule CatchAllModule {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
51 get {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
52 return _CatchAllModule;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
53 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
54 set {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
55 _CatchAllModule = value;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
56 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
57 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
58
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
59 public Int32 ThrottleRate {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
60 get { return _ThrottleRate; }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
61 set {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
62 if (value < 0) throw new ArgumentOutOfRangeException("value");
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
63 _ThrottleRate = value;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
64 if (_Listener == null) return;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
65 if (value == 0 && _ThrottleTimer != null) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
66 _ThrottleTimer.Dispose();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
67 _ThrottleTimer = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
68 } else if (value > 0 && _ThrottleTimer == null) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
69 _ThrottleTimer = new Timer(ThrottleCallback, null, 1000, 1000);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
70 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
71 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
72 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
73 public Int32 ThrottleBurst {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
74 get { return _ThrottleBurst; }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
75 set {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
76 if (value < 1) throw new ArgumentOutOfRangeException("value");
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
77 _ThrottleBurst = value;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
78 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
79 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
80
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
81 public EndPoint LocalEndPoint { get { return _Listener.LocalEndPoint; } }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
82
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
83 public void Listen(int Port) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
84 Listen(AddressFamily.InterNetwork, Port);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
85 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
86 public void Listen(AddressFamily af, int Port) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
87 Stop();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
88
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
89 _Listener = new Socket(af, SocketType.Stream, ProtocolType.Tcp);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
90
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
91 _Listener.Blocking = false;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
92 _Listener.Bind(new IPEndPoint(af == AddressFamily.InterNetworkV6 ? IPAddress.IPv6Any : IPAddress.Any, Port));
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
93 _Listener.Listen(25);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
94 _ThrottleCounter = _ThrottleBurst;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
95 _Listener.BeginAccept(AcceptCallback, null);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
96
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
97 if (_ThrottleRate > 0) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
98 _ThrottleTimer = new Timer(ThrottleCallback, null, 1000, 1000);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
99 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
100 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
101
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
102 public void Stop() {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
103 if (_ThrottleTimer != null) _ThrottleTimer.Dispose();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
104 if (_Listener != null && _Listener.IsBound) _Listener.Close();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
105 _Listener = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
106 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
107
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
108 public void Close() {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
109 Close(true);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
110 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
111 public void Close(bool CloseClients) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
112 Stop();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
113 if (CloseClients) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
114 _Clients.CloseAll();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
115 if (_Clients.Count > 0) Console.WriteLine("TCPServer.Close: Warning: " + _Clients.Count.ToString() + " connections were not properly terminated.");
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
116 } else {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
117 _Clients.Clear();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
118 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
119 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
120
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
121 private void AcceptCallback(System.IAsyncResult ar) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
122 Client Client = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
123 Socket Socket = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
124 if (_Listener == null) return;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
125 try {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
126 Socket = _Listener.EndAccept(ar);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
127 } catch (ObjectDisposedException) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
128 Console.WriteLine("TCPServer.AcceptCallback Listener object has been disposed. Aborting.");
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
129 return;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
130 } catch (SocketException ex) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
131 Console.WriteLine("TCPServer.AcceptCallback SocketException: " + ex.Message);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
132 Socket = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
133 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
134 if (Socket != null) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
135 try {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
136 Client = new Client(Socket, this);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
137 _Clients.Add(Client);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
138 if (ClientAccepted != null) ClientAccepted(this, new ClientAcceptedEventArgs(Client));
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
139 Client.Start(_ThreadPool);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
140 } catch (Exception ex) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
141 Console.WriteLine(ex.ToString());
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
142 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
143 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
144 if (_ThrottleCounter > 0 || _ThrottleRate == 0) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
145 _ThrottleCounter--;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
146 _Listener.BeginAccept(AcceptCallback, null);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
147 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
148 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
149
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
150 private void ThrottleCallback(Object state) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
151 if (_Listener == null) return;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
152 if (_ThrottleRate == 0) return;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
153 if (_ThrottleCounter >= _ThrottleBurst) return;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
154 if (_ThrottleCounter <= 0) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
155 _Listener.BeginAccept(AcceptCallback, null);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
156 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
157 _ThrottleRate += _ThrottleRate;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
158 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
159
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
160 public interface IModule {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
161 // Return value: True = Close connection, False = keep alive
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
162 bool Accept(TCPStream Stream);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
163 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
164
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
165 private class Client : TCPStream {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
166 private TCPServer _Server;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
167 private UCIS.ThreadPool.WorkItem _WorkItem;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
168 private IModule _Module;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
169 private byte _MagicNumber;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
170
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
171 public TCPServer Server {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
172 get { return _Server; }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
173 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
174 public IModule Module {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
175 get { return _Module; }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
176 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
177
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
178 private void _Stream_Closed(object sender, EventArgs e) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
179 _WorkItem = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
180 _Module = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
181 _Server = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
182 base.Closed -= _Stream_Closed;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
183 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
184
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
185 internal Client(Socket Socket, TCPServer Server) : base(Socket) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
186 _Server = Server;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
187 Socket.Blocking = true;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
188 base.Closed += _Stream_Closed;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
189 this.Tag = Server;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
190 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
191
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
192 internal void Start(UCIS.ThreadPool Pool) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
193 _WorkItem = Pool.QueueWorkItem(WorkerProc, null);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
194 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
195
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
196 private void WorkerProc(object state) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
197 bool CloseSocket = true;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
198 try {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
199 try {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
200 base.Blocking = true;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
201 //base.NoDelay = true;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
202 base.ReadTimeout = 5000;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
203 base.WriteBufferSize = 1024 * 10;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
204 base.ReadBufferSize = 1024 * 10;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
205 //Console.WriteLine("TCPServer: Accepted connection from " + base.Socket.RemoteEndPoint.ToString());
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
206 _MagicNumber = (byte)base.PeekByte();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
207 } catch (TimeoutException ex) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
208 Console.WriteLine("TCPServer: Caught TimeoutException while reading magic number: " + ex.Message);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
209 return;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
210 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
211 if (_Server._Modules.TryGetValue(_MagicNumber, out _Module)) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
212 this.Tag = _Module;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
213 CloseSocket = _Module.Accept(this);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
214 } else if (_Server._CatchAllModule != null) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
215 this.Tag = _Server._CatchAllModule;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
216 CloseSocket = _Server._CatchAllModule.Accept(this);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
217 } else {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
218 this.Tag = this;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
219 Console.WriteLine("TCPServer: Unknown magic number: " + _MagicNumber.ToString());
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
220 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
221 } catch (ThreadAbortException) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
222 Console.WriteLine("TCPServer: Caught ThreadAbortException");
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
223 } catch (SocketException ex) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
224 Console.WriteLine("TCPServer: Caught SocketException: " + ex.Message);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
225 } catch (Exception ex) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
226 Console.WriteLine("TCPServer: Caught Exception: " + ex.ToString());
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
227 } finally {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
228 try {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
229 if (CloseSocket) base.Close();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
230 } catch { }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
231 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
232 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
233 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
234 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
235 }