Dreamine.PLC.Omron.Fins
1.0.1
Dreamine.PLC.Omron.Fins 산업 자동화 및 I/O 기능을 제공합니다.
Toggle main menu visibility
로딩중...
검색중...
일치하는것 없음
OmronFinsTcpSimulatorServer.cs
이 파일의 문서화 페이지로 가기
1
using
System.Net;
2
using
System.Net.Sockets;
3
using
Dreamine.PLC.Core.Memory;
4
using
Dreamine.PLC.Omron.Fins.Protocol
;
5
6
namespace
Dreamine.PLC.Omron.Fins.Simulation
;
7
16
public
sealed
class
OmronFinsTcpSimulatorServer
: IAsyncDisposable
17
{
26
private
readonly
OmronFinsSimulatorServerOptions
_options
;
35
private
readonly InMemoryPlcMemory
_memory
;
44
private
readonly
OmronFinsSimulatorProtocol
_protocol
;
53
private
readonly List<TcpClient>
_clients
= [];
62
private
readonly
object
_syncRoot
=
new
();
71
private
TcpListener?
_listener
;
80
private
CancellationTokenSource?
_cts
;
89
private
Task?
_acceptTask
;
90
115
public
OmronFinsTcpSimulatorServer
(
OmronFinsSimulatorServerOptions
options)
116
: this(options, new InMemoryPlcMemory())
117
{
118
}
119
152
public
OmronFinsTcpSimulatorServer
(
OmronFinsSimulatorServerOptions
options, InMemoryPlcMemory memory)
153
{
154
_options
= options ??
throw
new
ArgumentNullException(nameof(options));
155
_memory
= memory ??
throw
new
ArgumentNullException(nameof(memory));
156
_protocol
=
new
OmronFinsSimulatorProtocol
(
_memory
,
_options
);
157
_protocol.StatusChanged += (_, message) =>
StatusChanged
?.Invoke(
this
, message);
158
}
159
168
public
event
EventHandler<string>?
StatusChanged
;
169
178
public
bool
IsRunning
=>
_listener
is not
null
;
179
212
public
Task
StartAsync
()
213
{
214
if
(
IsRunning
)
215
{
216
return
Task.CompletedTask;
217
}
218
219
var address =
ParseAddress
(
_options
.Host);
220
221
_cts
=
new
CancellationTokenSource();
222
_listener
=
new
TcpListener(address,
_options
.Port);
223
_listener
.Start();
224
_acceptTask
=
AcceptLoopAsync
(
_cts
.Token);
225
StatusChanged
?.Invoke(
this
, $
"FINS TCP simulator listening on {_options.Host}:{_options.Port}."
);
226
return
Task.CompletedTask;
227
}
228
245
public
async Task
StopAsync
()
246
{
247
if
(!
IsRunning
)
248
{
249
return
;
250
}
251
252
_cts
?.Cancel();
253
_listener
?.Stop();
254
_listener
=
null
;
255
256
TcpClient[] clients;
257
lock (
_syncRoot
)
258
{
259
clients =
_clients
.ToArray();
260
_clients
.Clear();
261
}
262
263
foreach
(var client
in
clients)
264
{
265
client.Dispose();
266
}
267
268
if
(
_acceptTask
is not
null
)
269
{
270
try
271
{
272
await
_acceptTask
.ConfigureAwait(
false
);
273
}
274
catch
(OperationCanceledException)
275
{
276
}
277
catch
(ObjectDisposedException)
278
{
279
}
280
catch
(SocketException)
281
{
282
}
283
}
284
285
_cts
?.Dispose();
286
_cts
=
null
;
287
_acceptTask
=
null
;
288
StatusChanged
?.Invoke(
this
,
"FINS TCP simulator stopped."
);
289
}
290
307
public
async ValueTask
DisposeAsync
()
308
{
309
await
StopAsync
().ConfigureAwait(
false
);
310
}
311
312
337
private
static
IPAddress
ParseAddress
(
string
host)
338
{
339
if
(
string
.IsNullOrWhiteSpace(host) || host ==
"0.0.0.0"
|| host ==
"*"
|| host ==
"+"
)
340
{
341
return
IPAddress.Any;
342
}
343
344
return
IPAddress.TryParse(host, out var address) ? address : IPAddress.Any;
345
}
346
379
private
async Task
AcceptLoopAsync
(CancellationToken cancellationToken)
380
{
381
while
(!cancellationToken.IsCancellationRequested &&
_listener
is not
null
)
382
{
383
TcpClient client;
384
385
try
386
{
387
client = await
_listener
.AcceptTcpClientAsync(cancellationToken).ConfigureAwait(
false
);
388
}
389
catch
(OperationCanceledException)
390
{
391
break
;
392
}
393
catch
(ObjectDisposedException)
394
{
395
break
;
396
}
397
catch
(SocketException) when (cancellationToken.IsCancellationRequested)
398
{
399
break
;
400
}
401
402
lock (
_syncRoot
)
403
{
404
_clients
.Add(client);
405
}
406
407
_ = Task.Run(() =>
ClientLoopAsync
(client, cancellationToken), cancellationToken);
408
}
409
}
410
443
private
async Task
ClientLoopAsync
(TcpClient client, CancellationToken cancellationToken)
444
{
445
try
446
{
447
using
(client)
448
{
449
var stream = client.GetStream();
450
while
(!cancellationToken.IsCancellationRequested && client.Connected)
451
{
452
var packet = await
ReceiveFinsTcpPacketAsync
(stream, cancellationToken).ConfigureAwait(
false
);
453
var request =
OmronFinsTcpPacket
.
Extract
(packet);
454
var response =
_protocol
.HandleRequest(request);
455
var responsePacket =
OmronFinsTcpPacket
.
Wrap
(response);
456
await stream.WriteAsync(responsePacket, cancellationToken).ConfigureAwait(
false
);
457
await stream.FlushAsync(cancellationToken).ConfigureAwait(
false
);
458
}
459
}
460
}
461
catch
(OperationCanceledException)
462
{
463
}
464
catch
(IOException)
465
{
466
}
467
catch
(SocketException)
468
{
469
}
470
catch
(ObjectDisposedException)
471
{
472
}
473
catch
(Exception ex)
474
{
475
StatusChanged
?.Invoke(
this
, $
"FINS TCP client error: {ex.Message}"
);
476
}
477
finally
478
{
479
lock (
_syncRoot
)
480
{
481
_clients
.Remove(client);
482
}
483
}
484
}
485
542
private
static
async Task<byte[]>
ReceiveFinsTcpPacketAsync
(NetworkStream stream, CancellationToken cancellationToken)
543
{
544
var header =
new
byte
[16];
545
await
ReadExactlyAsync
(stream, header, cancellationToken).ConfigureAwait(
false
);
546
var length =
OmronFinsEndian
.
ReadInt32
(header, 4);
547
if
(length < 8)
548
{
549
throw
new
InvalidOperationException($
"Invalid FINS/TCP packet length: {length}."
);
550
}
551
552
var body =
new
byte
[length - 8];
553
await
ReadExactlyAsync
(stream, body, cancellationToken).ConfigureAwait(
false
);
554
var packet =
new
byte
[header.Length + body.Length];
555
Buffer.BlockCopy(header, 0, packet, 0, header.Length);
556
Buffer.BlockCopy(body, 0, packet, header.Length, body.Length);
557
return
packet;
558
}
559
616
private
static
async Task
ReadExactlyAsync
(NetworkStream stream,
byte
[] buffer, CancellationToken cancellationToken)
617
{
618
var offset = 0;
619
while
(offset < buffer.Length)
620
{
621
var read = await stream.ReadAsync(buffer.AsMemory(offset, buffer.Length - offset), cancellationToken).ConfigureAwait(
false
);
622
if
(read == 0)
623
{
624
throw
new
IOException(
"The FINS TCP client closed the connection."
);
625
}
626
627
offset += read;
628
}
629
}
630
}
Dreamine.PLC.Omron.Fins.Protocol
Definition
OmronFinsCommand.cs:1
Dreamine.PLC.Omron.Fins.Simulation
Definition
OmronFinsSimulatorProtocol.cs:7
Dreamine.PLC.Omron.Fins.Protocol.OmronFinsEndian
Definition
OmronFinsEndian.cs:12
Dreamine.PLC.Omron.Fins.Protocol.OmronFinsEndian.ReadInt32
static int ReadInt32(ReadOnlySpan< byte > buffer, int offset)
Definition
OmronFinsEndian.cs:143
Dreamine.PLC.Omron.Fins.Protocol.OmronFinsTcpPacket
Definition
OmronFinsTcpPacket.cs:14
Dreamine.PLC.Omron.Fins.Protocol.OmronFinsTcpPacket.Extract
static byte[] Extract(ReadOnlySpan< byte > packet)
Definition
OmronFinsTcpPacket.cs:107
Dreamine.PLC.Omron.Fins.Protocol.OmronFinsTcpPacket.Wrap
static byte[] Wrap(IReadOnlyList< byte > finsFrame)
Definition
OmronFinsTcpPacket.cs:57
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsSimulatorProtocol
Definition
OmronFinsSimulatorProtocol.cs:18
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsSimulatorServerOptions
Definition
OmronFinsSimulatorServerOptions.cs:12
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer._options
readonly OmronFinsSimulatorServerOptions _options
Definition
OmronFinsTcpSimulatorServer.cs:26
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.ParseAddress
static IPAddress ParseAddress(string host)
Definition
OmronFinsTcpSimulatorServer.cs:337
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.ReceiveFinsTcpPacketAsync
static async Task< byte[]> ReceiveFinsTcpPacketAsync(NetworkStream stream, CancellationToken cancellationToken)
Definition
OmronFinsTcpSimulatorServer.cs:542
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.OmronFinsTcpSimulatorServer
OmronFinsTcpSimulatorServer(OmronFinsSimulatorServerOptions options)
Definition
OmronFinsTcpSimulatorServer.cs:115
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.StopAsync
async Task StopAsync()
Definition
OmronFinsTcpSimulatorServer.cs:245
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.StatusChanged
EventHandler< string >? StatusChanged
Definition
OmronFinsTcpSimulatorServer.cs:168
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.StartAsync
Task StartAsync()
Definition
OmronFinsTcpSimulatorServer.cs:212
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.DisposeAsync
async ValueTask DisposeAsync()
Definition
OmronFinsTcpSimulatorServer.cs:307
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer._cts
CancellationTokenSource? _cts
Definition
OmronFinsTcpSimulatorServer.cs:80
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer._listener
TcpListener? _listener
Definition
OmronFinsTcpSimulatorServer.cs:71
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.IsRunning
bool IsRunning
Definition
OmronFinsTcpSimulatorServer.cs:178
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.ReadExactlyAsync
static async Task ReadExactlyAsync(NetworkStream stream, byte[] buffer, CancellationToken cancellationToken)
Definition
OmronFinsTcpSimulatorServer.cs:616
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.AcceptLoopAsync
async Task AcceptLoopAsync(CancellationToken cancellationToken)
Definition
OmronFinsTcpSimulatorServer.cs:379
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.ClientLoopAsync
async Task ClientLoopAsync(TcpClient client, CancellationToken cancellationToken)
Definition
OmronFinsTcpSimulatorServer.cs:443
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer._acceptTask
Task? _acceptTask
Definition
OmronFinsTcpSimulatorServer.cs:89
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer._memory
readonly InMemoryPlcMemory _memory
Definition
OmronFinsTcpSimulatorServer.cs:35
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer.OmronFinsTcpSimulatorServer
OmronFinsTcpSimulatorServer(OmronFinsSimulatorServerOptions options, InMemoryPlcMemory memory)
Definition
OmronFinsTcpSimulatorServer.cs:152
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer._syncRoot
readonly object _syncRoot
Definition
OmronFinsTcpSimulatorServer.cs:62
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer._protocol
readonly OmronFinsSimulatorProtocol _protocol
Definition
OmronFinsTcpSimulatorServer.cs:44
Dreamine.PLC.Omron.Fins.Simulation.OmronFinsTcpSimulatorServer._clients
readonly List< TcpClient > _clients
Definition
OmronFinsTcpSimulatorServer.cs:53
Simulation
OmronFinsTcpSimulatorServer.cs
다음에 의해 생성됨 :
1.17.0