-
Notifications
You must be signed in to change notification settings - Fork 1
/
TunnelServer.cs
119 lines (113 loc) · 3.86 KB
/
TunnelServer.cs
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
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Net;
using System.Net.Sockets;
using System.Threading;
public class TunnelServer
{
private bool running = true;
private NetworkHandler networkHandler;
private ConcurrentDictionary<int, TcpClient> clients = new ConcurrentDictionary<int, TcpClient>();
private byte[] readBuffer = new byte[16 * 1024];
private Thread networkLoop;
private IPEndPoint connectEndpoint;
public TunnelServer(NetworkHandler networkHandler, Settings settings)
{
this.networkHandler = networkHandler;
this.connectEndpoint = settings.ipEndpoint;
networkHandler.SetServer(this);
networkLoop = new Thread(new ThreadStart(NetworkLoop));
networkLoop.Start();
}
public void NetworkLoop()
{
while (running)
{
int disconnectClient = 0;
bool activity = false;
foreach (KeyValuePair<int, TcpClient> kvp in clients)
{
int clientID = kvp.Key;
TcpClient readClient = kvp.Value;
if (readClient.Connected && readClient.Available > 0)
{
activity = true;
try
{
int readBytes = readClient.GetStream().Read(readBuffer, 0, readBuffer.Length);
networkHandler.HandleTCPMessage(clientID, readBuffer, readBytes);
}
catch (Exception e)
{
Console.WriteLine("Error during TCP read: " + e.Message);
disconnectClient = clientID;
}
}
if (readClient.Connected)
{
byte[] sendMessage = networkHandler.GetTCPMessage(clientID);
if (sendMessage != null)
{
activity = true;
try
{
readClient.GetStream().Write(sendMessage, 0, sendMessage.Length);
}
catch (Exception e)
{
Console.WriteLine("Error during TCP write: " + e.Message);
disconnectClient = clientID;
}
}
}
if (networkHandler.ShouldDisconnect(clientID))
{
Console.WriteLine("UDP Timeout for connection " + clientID);
disconnectClient = clientID;
}
}
if (disconnectClient != 0)
{
DisconnectClient(disconnectClient);
}
if (!activity)
{
Thread.Sleep(10);
}
}
}
public void DisconnectClient(int clientID)
{
if (clients.ContainsKey(clientID))
{
if (clients.TryRemove(clientID, out TcpClient disconnectTcpClient))
{
if (disconnectTcpClient.Connected)
{
try
{
disconnectTcpClient.Close();
}
catch (Exception e)
{
Console.WriteLine("Error disconnecting TCP client " + clientID + ", " + e.Message);
}
}
}
networkHandler.ForgetClient(clientID);
}
}
public TcpClient GetNewConnection(int clientID)
{
TcpClient newClient = new TcpClient(connectEndpoint.AddressFamily);
newClient.NoDelay = true;
newClient.Connect(connectEndpoint);
clients.TryAdd(clientID, newClient);
return newClient;
}
public void Shutdown()
{
running = false;
}
}