Dreamine.PLC.Mitsubishi.MC
1.0.1
Dreamine.PLC.Mitsubishi.MC 산업 자동화 및 I/O 기능을 제공합니다.
Toggle main menu visibility
로딩중...
검색중...
일치하는것 없음
MitsubishiMcTcpSimulatorServer.cs
이 파일의 문서화 페이지로 가기
1
using
System.Net;
2
using
System.Net.Sockets;
3
using
Dreamine.PLC.Core.Memory;
4
5
namespace
Dreamine.PLC.Mitsubishi.MC.Simulation
;
6
15
public
sealed
class
MitsubishiMcTcpSimulatorServer
: IAsyncDisposable
16
{
25
private
readonly
MitsubishiMcSimulatorServerOptions
_options
;
34
private
readonly
MitsubishiMcBinary3ESimulatorProtocol
_protocol
;
43
private
readonly List<Task>
_clientTasks
= [];
52
private
readonly
object
_syncRoot
=
new
();
61
private
CancellationTokenSource?
_cts
;
70
private
TcpListener?
_listener
;
79
private
Task?
_acceptTask
;
80
104
public
MitsubishiMcTcpSimulatorServer
(
MitsubishiMcSimulatorServerOptions
options)
105
: this(options, new InMemoryPlcMemory())
106
{
107
}
108
139
public
MitsubishiMcTcpSimulatorServer
(
MitsubishiMcSimulatorServerOptions
options, InMemoryPlcMemory memory)
140
{
141
_options
= options ??
throw
new
ArgumentNullException(nameof(options));
142
_protocol
=
new
MitsubishiMcBinary3ESimulatorProtocol
(memory ??
throw
new
ArgumentNullException(nameof(memory)), options);
143
_protocol.StatusChanged +=
OnProtocolStatusChanged
;
144
}
145
154
public
event
EventHandler<string>?
StatusChanged
;
155
164
public
bool
IsRunning
=>
_listener
is not
null
;
165
189
public
Task
StartAsync
(CancellationToken cancellationToken =
default
)
190
{
191
if
(
_listener
is not
null
)
192
{
193
return
Task.CompletedTask;
194
}
195
196
var address =
ParseAddress
(
_options
.Host);
197
_listener
=
new
TcpListener(address,
_options
.Port);
198
_listener
.Start();
199
_cts
= CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
200
_acceptTask
= Task.Run(() =>
AcceptLoopAsync
(
_cts
.Token), CancellationToken.None);
201
StatusChanged
?.Invoke(
this
, $
"MC TCP simulator server started. {_options.Host}:{_options.Port}"
);
202
return
Task.CompletedTask;
203
}
204
221
public
async Task
StopAsync
()
222
{
223
if
(
_listener
is
null
)
224
{
225
return
;
226
}
227
228
_cts
?.Cancel();
229
_listener
.Stop();
230
_listener
=
null
;
231
232
if
(
_acceptTask
is not
null
)
233
{
234
try
235
{
236
await
_acceptTask
.ConfigureAwait(
false
);
237
}
238
catch
(OperationCanceledException)
239
{
240
}
241
catch
(ObjectDisposedException)
242
{
243
}
244
}
245
246
Task[] clientTasks;
247
lock (
_syncRoot
)
248
{
249
clientTasks =
_clientTasks
.ToArray();
250
_clientTasks
.Clear();
251
}
252
253
try
254
{
255
await Task.WhenAll(clientTasks).ConfigureAwait(
false
);
256
}
257
catch
258
{
259
}
260
261
_cts
?.Dispose();
262
_cts
=
null
;
263
StatusChanged
?.Invoke(
this
,
"MC TCP simulator server stopped."
);
264
}
265
281
public
async ValueTask
DisposeAsync
()
282
{
283
_protocol.StatusChanged -=
OnProtocolStatusChanged
;
284
await
StopAsync
().ConfigureAwait(
false
);
285
}
286
309
private
async Task
AcceptLoopAsync
(CancellationToken cancellationToken)
310
{
311
while
(!cancellationToken.IsCancellationRequested &&
_listener
is not
null
)
312
{
313
TcpClient client;
314
315
try
316
{
317
client = await
_listener
.AcceptTcpClientAsync(cancellationToken).ConfigureAwait(
false
);
318
}
319
catch
(OperationCanceledException)
320
{
321
break
;
322
}
323
catch
(ObjectDisposedException)
324
{
325
break
;
326
}
327
328
var task = Task.Run(() =>
HandleClientAsync
(client, cancellationToken), CancellationToken.None);
329
lock (
_syncRoot
)
330
{
331
_clientTasks
.RemoveAll(
static
item => item.IsCompleted);
332
_clientTasks
.Add(task);
333
}
334
}
335
}
336
366
private
async Task
HandleClientAsync
(TcpClient client, CancellationToken cancellationToken)
367
{
368
using
(client)
369
using
(var stream = client.GetStream())
370
{
371
StatusChanged
?.Invoke(
this
,
"MC TCP simulator client connected."
);
372
373
while
(!cancellationToken.IsCancellationRequested)
374
{
375
byte
[] request;
376
try
377
{
378
request = await
ReceiveBinary3EFrameAsync
(stream, cancellationToken).ConfigureAwait(
false
);
379
}
380
catch
(OperationCanceledException)
381
{
382
break
;
383
}
384
catch
(IOException)
385
{
386
break
;
387
}
388
catch
(ObjectDisposedException)
389
{
390
break
;
391
}
392
393
var response =
_protocol
.Execute(request);
394
await stream.WriteAsync(response, cancellationToken).ConfigureAwait(
false
);
395
await stream.FlushAsync(cancellationToken).ConfigureAwait(
false
);
396
}
397
}
398
399
StatusChanged
?.Invoke(
this
,
"MC TCP simulator client disconnected."
);
400
}
401
445
private
static
async Task<byte[]>
ReceiveBinary3EFrameAsync
(NetworkStream stream, CancellationToken cancellationToken)
446
{
447
var header =
new
byte
[9];
448
await
ReadExactlyAsync
(stream, header, cancellationToken).ConfigureAwait(
false
);
449
450
var requestDataLength = header[7] | (header[8] << 8);
451
if
(requestDataLength < 2)
452
{
453
throw
new
InvalidOperationException($
"Invalid MC request data length: {requestDataLength}"
);
454
}
455
456
var body =
new
byte
[requestDataLength];
457
await
ReadExactlyAsync
(stream, body, cancellationToken).ConfigureAwait(
false
);
458
459
var frame =
new
byte
[header.Length + body.Length];
460
Buffer.BlockCopy(header, 0, frame, 0, header.Length);
461
Buffer.BlockCopy(body, 0, frame, header.Length, body.Length);
462
return
frame;
463
}
464
508
private
static
async Task
ReadExactlyAsync
(NetworkStream stream,
byte
[] buffer, CancellationToken cancellationToken)
509
{
510
var offset = 0;
511
while
(offset < buffer.Length)
512
{
513
var read = await stream.ReadAsync(buffer.AsMemory(offset, buffer.Length - offset), cancellationToken).ConfigureAwait(
false
);
514
if
(read == 0)
515
{
516
throw
new
IOException(
"The MC TCP simulator client closed the connection."
);
517
}
518
519
offset += read;
520
}
521
}
522
545
private
static
IPAddress
ParseAddress
(
string
host)
546
{
547
if
(
string
.IsNullOrWhiteSpace(host) || host ==
"*"
|| host ==
"+"
)
548
{
549
return
IPAddress.Any;
550
}
551
552
return
IPAddress.TryParse(host, out var address) ? address : IPAddress.Any;
553
}
554
577
private
void
OnProtocolStatusChanged
(
object
? sender,
string
e)
578
{
579
StatusChanged
?.Invoke(
this
, e);
580
}
581
}
Dreamine.PLC.Mitsubishi.MC.Simulation
Definition
MitsubishiMcBinary3ESimulatorProtocol.cs:6
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcBinary3ESimulatorProtocol
Definition
MitsubishiMcBinary3ESimulatorProtocol.cs:17
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcSimulatorServerOptions
Definition
MitsubishiMcSimulatorServerOptions.cs:12
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.StartAsync
Task StartAsync(CancellationToken cancellationToken=default)
Definition
MitsubishiMcTcpSimulatorServer.cs:189
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.HandleClientAsync
async Task HandleClientAsync(TcpClient client, CancellationToken cancellationToken)
Definition
MitsubishiMcTcpSimulatorServer.cs:366
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.DisposeAsync
async ValueTask DisposeAsync()
Definition
MitsubishiMcTcpSimulatorServer.cs:281
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer._listener
TcpListener? _listener
Definition
MitsubishiMcTcpSimulatorServer.cs:70
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.StatusChanged
EventHandler< string >? StatusChanged
Definition
MitsubishiMcTcpSimulatorServer.cs:154
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer._acceptTask
Task? _acceptTask
Definition
MitsubishiMcTcpSimulatorServer.cs:79
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.IsRunning
bool IsRunning
Definition
MitsubishiMcTcpSimulatorServer.cs:164
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer._clientTasks
readonly List< Task > _clientTasks
Definition
MitsubishiMcTcpSimulatorServer.cs:43
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.StopAsync
async Task StopAsync()
Definition
MitsubishiMcTcpSimulatorServer.cs:221
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.ReceiveBinary3EFrameAsync
static async Task< byte[]> ReceiveBinary3EFrameAsync(NetworkStream stream, CancellationToken cancellationToken)
Definition
MitsubishiMcTcpSimulatorServer.cs:445
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer._syncRoot
readonly object _syncRoot
Definition
MitsubishiMcTcpSimulatorServer.cs:52
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.ReadExactlyAsync
static async Task ReadExactlyAsync(NetworkStream stream, byte[] buffer, CancellationToken cancellationToken)
Definition
MitsubishiMcTcpSimulatorServer.cs:508
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.ParseAddress
static IPAddress ParseAddress(string host)
Definition
MitsubishiMcTcpSimulatorServer.cs:545
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer._cts
CancellationTokenSource? _cts
Definition
MitsubishiMcTcpSimulatorServer.cs:61
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.MitsubishiMcTcpSimulatorServer
MitsubishiMcTcpSimulatorServer(MitsubishiMcSimulatorServerOptions options, InMemoryPlcMemory memory)
Definition
MitsubishiMcTcpSimulatorServer.cs:139
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.OnProtocolStatusChanged
void OnProtocolStatusChanged(object? sender, string e)
Definition
MitsubishiMcTcpSimulatorServer.cs:577
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer._options
readonly MitsubishiMcSimulatorServerOptions _options
Definition
MitsubishiMcTcpSimulatorServer.cs:25
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.AcceptLoopAsync
async Task AcceptLoopAsync(CancellationToken cancellationToken)
Definition
MitsubishiMcTcpSimulatorServer.cs:309
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer._protocol
readonly MitsubishiMcBinary3ESimulatorProtocol _protocol
Definition
MitsubishiMcTcpSimulatorServer.cs:34
Dreamine.PLC.Mitsubishi.MC.Simulation.MitsubishiMcTcpSimulatorServer.MitsubishiMcTcpSimulatorServer
MitsubishiMcTcpSimulatorServer(MitsubishiMcSimulatorServerOptions options)
Definition
MitsubishiMcTcpSimulatorServer.cs:104
Simulation
MitsubishiMcTcpSimulatorServer.cs
다음에 의해 생성됨 :
1.17.0