1
1
using System ;
2
+ using System . Collections . Generic ;
3
+ using System . Linq ;
2
4
using System . Net ;
3
5
using System . Net . Sockets ;
4
- using System . Threading . Tasks ;
6
+ using System . Threading . Tasks ;
5
7
using TcpUdpTool . Model . Data ;
6
8
using TcpUdpTool . Model . EventArg ;
7
9
@@ -13,23 +15,37 @@ public class TcpServer : IDisposable
13
15
public event EventHandler < ReceivedEventArgs > Received ;
14
16
public event EventHandler < TcpServerStatusEventArgs > StatusChanged ;
15
17
16
-
17
18
private TcpListener _tcpServer ;
18
- private System . Net . Sockets . TcpClient _connectedClient ;
19
+ private List < System . Net . Sockets . TcpClient > _connectedClients ;
19
20
private byte [ ] _buffer ;
20
21
21
22
23
+ public int NumConnectedClients
24
+ {
25
+ get
26
+ {
27
+ int count = 0 ;
28
+ lock ( _connectedClients )
29
+ {
30
+ count = _connectedClients . Count ;
31
+ }
32
+
33
+ return count ;
34
+ }
35
+ }
36
+
37
+
22
38
public TcpServer ( )
23
39
{
40
+ _connectedClients = new List < System . Net . Sockets . TcpClient > ( ) ;
24
41
_buffer = new byte [ 8192 ] ;
25
42
}
26
43
27
-
28
44
public void Start ( IPAddress ip , int port )
29
45
{
30
46
if ( _tcpServer != null )
31
47
return ;
32
-
48
+
33
49
try
34
50
{
35
51
_tcpServer = new TcpListener ( new IPEndPoint ( ip , port ) ) ;
@@ -56,30 +72,56 @@ public void Stop()
56
72
}
57
73
}
58
74
59
- public async Task < TransmissionResult > SendAsync ( Transmission msg )
60
- {
61
- if ( _connectedClient == null )
62
- {
63
- return null ;
64
- }
75
+ public async Task < List < TransmissionResult > > SendAsync ( Transmission msg )
76
+ {
77
+ var result = new List < TransmissionResult > ( ) ;
65
78
66
- IPEndPoint from = _connectedClient . Client . LocalEndPoint as IPEndPoint ;
67
- IPEndPoint to = _connectedClient . Client . RemoteEndPoint as IPEndPoint ;
79
+ List < System . Net . Sockets . TcpClient > copy ;
80
+ lock ( _connectedClients )
81
+ {
82
+ copy = _connectedClients . ToList ( ) ;
83
+ }
68
84
69
- await _connectedClient . GetStream ( ) . WriteAsync ( msg . Data , 0 , msg . Length ) ;
85
+ foreach ( var c in copy )
86
+ {
87
+ IPEndPoint from = c . Client . LocalEndPoint as IPEndPoint ;
88
+ IPEndPoint to = c . Client . RemoteEndPoint as IPEndPoint ;
89
+
90
+ try
91
+ {
92
+ await c . GetStream ( ) . WriteAsync ( msg . Data , 0 , msg . Length ) ;
93
+ result . Add ( new TransmissionResult { From = from , To = to } ) ;
94
+ }
95
+ catch ( Exception )
96
+ {
97
+ DisconnectClient ( c ) ;
98
+ }
99
+ }
70
100
71
- return new TransmissionResult ( ) { From = from , To = to } ;
101
+ return result ;
72
102
}
73
103
74
104
public void Disconnect ( )
75
105
{
76
106
// close client connection.
77
- if ( _connectedClient != null )
78
- {
79
- _connectedClient . Close ( ) ;
80
- _connectedClient = null ;
81
- OnStatusChanged ( TcpServerStatusEventArgs . EServerStatus . ClientDisconnected ) ;
82
- }
107
+
108
+ List < System . Net . Sockets . TcpClient > copy ;
109
+ lock ( _connectedClients )
110
+ {
111
+ copy = _connectedClients . ToList ( ) ;
112
+ }
113
+
114
+ foreach ( var c in copy )
115
+ {
116
+ OnClientStatusChanged ( TcpServerStatusEventArgs . EServerStatus . ClientDisconnected , c ) ;
117
+ c . Close ( ) ;
118
+ c . Dispose ( ) ;
119
+ }
120
+
121
+ lock ( _connectedClients )
122
+ {
123
+ _connectedClients . Clear ( ) ;
124
+ }
83
125
}
84
126
85
127
@@ -91,19 +133,13 @@ private void StartAcceptClient()
91
133
{
92
134
try
93
135
{
94
- System . Net . Sockets . TcpClient client = await _tcpServer . AcceptTcpClientAsync ( ) ;
95
-
96
- if ( _connectedClient == null )
97
- {
98
- _connectedClient = client ;
99
- OnStatusChanged ( TcpServerStatusEventArgs . EServerStatus . ClientConnected ) ;
100
- StartReceive ( ) ;
101
- }
102
- else
103
- {
104
- // only one connection allowed, close this request.
105
- client . Close ( ) ;
106
- }
136
+ var client = await _tcpServer . AcceptTcpClientAsync ( ) ;
137
+ lock ( _connectedClients )
138
+ {
139
+ _connectedClients . Add ( client ) ;
140
+ }
141
+ OnClientStatusChanged ( TcpServerStatusEventArgs . EServerStatus . ClientConnected , client ) ;
142
+ StartReceive ( client ) ;
107
143
}
108
144
catch ( Exception ex )
109
145
when ( ex is SocketException || ex is ObjectDisposedException )
@@ -115,58 +151,84 @@ private void StartAcceptClient()
115
151
} ) ;
116
152
}
117
153
118
- private void StartReceive ( )
154
+ private void StartReceive ( System . Net . Sockets . TcpClient client )
119
155
{
120
156
Task . Run ( async ( ) =>
121
- {
122
- while ( _connectedClient != null )
123
- {
124
- try
125
- {
126
- int read = await _connectedClient . GetStream ( ) . ReadAsync ( _buffer , 0 , _buffer . Length ) ;
127
-
128
- if ( read > 0 )
129
- {
130
- byte [ ] data = new byte [ read ] ;
131
- Array . Copy ( _buffer , data , read ) ;
132
-
133
-
134
- Transmission msg = new Transmission ( data , Transmission . EType . Received ) ;
135
- msg . Destination = _connectedClient . Client . LocalEndPoint as IPEndPoint ;
136
- msg . Origin = _connectedClient . Client . RemoteEndPoint as IPEndPoint ;
137
-
138
- Received ? . Invoke ( this , new ReceivedEventArgs ( msg ) ) ;
139
- }
140
- else
141
- {
142
- // server closed connection.
143
- Disconnect ( ) ;
144
- break ;
145
- }
146
- }
147
- catch ( Exception e )
148
- when ( e is ObjectDisposedException || e is InvalidOperationException )
149
- {
150
- Disconnect ( ) ;
151
- break ;
152
- }
157
+ {
158
+ bool stop = false ;
159
+ while ( ! stop )
160
+ {
161
+ try
162
+ {
163
+ int read = await client . GetStream ( ) . ReadAsync ( _buffer , 0 , _buffer . Length ) ;
164
+
165
+ if ( read > 0 )
166
+ {
167
+ byte [ ] data = new byte [ read ] ;
168
+ Array . Copy ( _buffer , data , read ) ;
169
+
170
+ Transmission msg = new Transmission ( data , Transmission . EType . Received ) ;
171
+ msg . Destination = client . Client . LocalEndPoint as IPEndPoint ;
172
+ msg . Origin = client . Client . RemoteEndPoint as IPEndPoint ;
173
+
174
+ Received ? . Invoke ( this , new ReceivedEventArgs ( msg ) ) ;
175
+ }
176
+ else
177
+ {
178
+ // server closed connection.
179
+ DisconnectClient ( client ) ;
180
+ stop = true ;
181
+ }
182
+ }
183
+ catch ( Exception e )
184
+ when ( e is ObjectDisposedException || e is InvalidOperationException )
185
+ {
186
+ DisconnectClient ( client ) ;
187
+ stop = true ;
188
+ }
153
189
}
154
190
} ) ;
155
191
}
156
192
157
193
private void OnStatusChanged ( TcpServerStatusEventArgs . EServerStatus status )
158
194
{
159
195
StatusChanged ? . Invoke ( this , new TcpServerStatusEventArgs ( status ,
160
- _tcpServer ? . LocalEndpoint as IPEndPoint ,
161
- _connectedClient ? . Client . RemoteEndPoint as IPEndPoint ) ) ;
196
+ _tcpServer ? . LocalEndpoint as IPEndPoint , null ) ) ;
197
+ }
198
+
199
+ private void OnClientStatusChanged ( TcpServerStatusEventArgs . EServerStatus status , System . Net . Sockets . TcpClient client )
200
+ {
201
+ StatusChanged ? . Invoke ( this , new TcpServerStatusEventArgs ( status ,
202
+ _tcpServer ? . LocalEndpoint as IPEndPoint , client . Client . RemoteEndPoint as IPEndPoint ) ) ;
203
+ }
204
+
205
+ private void DisconnectClient ( System . Net . Sockets . TcpClient client )
206
+ {
207
+ lock ( _connectedClients )
208
+ {
209
+ _connectedClients . Remove ( client ) ;
210
+ }
211
+
212
+ OnClientStatusChanged ( TcpServerStatusEventArgs . EServerStatus . ClientDisconnected , client ) ;
213
+ client . Close ( ) ;
214
+ client . Dispose ( ) ;
162
215
}
163
216
164
217
public void Dispose ( )
165
218
{
219
+ lock ( _connectedClients )
220
+ {
221
+ foreach ( var c in _connectedClients )
222
+ {
223
+ c . Close ( ) ;
224
+ c . Dispose ( ) ;
225
+ }
226
+
227
+ _connectedClients . Clear ( ) ;
228
+ }
229
+
166
230
_tcpServer ? . Stop ( ) ;
167
231
_tcpServer = null ;
168
- _connectedClient ? . Close ( ) ;
169
- _connectedClient = null ;
170
232
}
171
233
}
172
234
0 commit comments