-
Notifications
You must be signed in to change notification settings - Fork 1
/
SCL_SocketServer.cs
161 lines (138 loc) · 4.49 KB
/
SCL_SocketServer.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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
using UnityEngine;
using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Globalization;
using System.Text;
using System.Reflection;
using System.Threading;
public class SCL_SocketClientThreadHolder
{
protected readonly Thread thread;
protected readonly SCL_ClientSocketHandler handler;
public Thread Thread {
get {
return this.thread;
}
}
public SCL_ClientSocketHandler Handler {
get {
return this.handler;
}
}
public SCL_SocketClientThreadHolder (Thread thread, SCL_ClientSocketHandler handler)
{
this.thread = thread;
this.handler = handler;
}
}
public class SCL_SocketServer
{
protected readonly TcpListener listener = null;
protected readonly SCL_IClientSocketHandlerDelegate clientSocketHandlerDelegate;
protected readonly string separatorString;
protected readonly Encoding encoding;
protected ArrayList clientHandlerThreads;
protected readonly int portNumber;
protected readonly IPEndPoint localEndPoint;
protected readonly int maxClients;
public int PortNumber {
get {
return this.portNumber;
}
}
public IPEndPoint LocalEndPoint {
get {
return this.localEndPoint;
}
}
public int MaxClients {
get {
return this.maxClients;
}
}
public int ClientCount {
get {
return this.clientHandlerThreads.Count;
}
}
public SCL_SocketServer (SCL_IClientSocketHandlerDelegate clientSocketHandlerDelegate,
int maxClients = 1,
string separatorString = "\n",
int portNumber = 13000,
Encoding encoding = null)
{
this.portNumber = portNumber;
this.clientSocketHandlerDelegate = clientSocketHandlerDelegate;
this.separatorString = separatorString;
this.encoding = (encoding != null) ? encoding : Encoding.UTF8;
this.clientHandlerThreads = ArrayList.Synchronized(new ArrayList());
this.maxClients = maxClients;
// this is the local endpoing through which we shall listen
// for connections. the ip is resolved dynamically and the
// host is somewhat arbitrary (can be set by user)
IPHostEntry ipHostInfo = Dns.GetHostEntry(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
this.localEndPoint = new IPEndPoint(ipAddress, this.portNumber);
// create the socket to listen to the tcp communication
this.listener = new TcpListener(this.localEndPoint.Address, this.portNumber);
Debug.Log("Created TCP listener.");
}
public void StartListeningForConnections()
{
Debug.Log("Began listening for TCP clients.");
this.listener.Start();
this.ListenForConnection();
}
protected void ListenForConnection()
{
this.listener.BeginAcceptTcpClient(new AsyncCallback(this.AcceptCallback), this.listener);
}
// NOT on main thread
protected void AcceptCallback(IAsyncResult ar)
{
int threadId = Thread.CurrentThread.ManagedThreadId;
Debug.Log ("Accept thread id: " + threadId);
TcpListener listener = (TcpListener)ar.AsyncState;
TcpClient client = listener.EndAcceptTcpClient(ar);
Debug.Log ("thread id " + threadId + " accepted client " + client.Client.RemoteEndPoint);
Debug.Log ("thread id " + threadId + " beginning read from client " + client.Client.RemoteEndPoint);
SCL_ClientSocketHandler clientHandler =
new SCL_ClientSocketHandler(client,
this.clientSocketHandlerDelegate,
this.separatorString,
this.encoding);
Thread clientThread = new Thread(new ThreadStart(clientHandler.Run));
this.clientHandlerThreads.Add(new SCL_SocketClientThreadHolder(clientThread, clientHandler));
clientThread.Start();
Debug.Log ("Client thread started");
if (this.ClientCount < this.maxClients)
{
Debug.Log ("client handler threads less than max clients. Listening again");
this.ListenForConnection();
}
else
{
Debug.Log (String.Format ("Max number of clients reached ({0}), stopping listening", this.maxClients));
this.StopListeningForConnections();
}
}
public void StopListeningForConnections() {
this.listener.Stop();
Debug.Log ("Stopped listening for connections");
}
public void Cleanup()
{
this.listener.Stop();
foreach(SCL_SocketClientThreadHolder holder in this.clientHandlerThreads)
{
Debug.Log ("calling stop on thread " + holder.Thread.ManagedThreadId);
holder.Handler.Cleanup();
Debug.Log ("Calling thread abort on thread: " + holder.Thread.ManagedThreadId);
holder.Thread.Abort();
}
this.clientHandlerThreads = null;
}
}