Dreamine.PLC.Omron.Fins
1.0.1
Dreamine.PLC.Omron.Fins 산업 자동화 및 I/O 기능을 제공합니다.
Toggle main menu visibility
로딩중...
검색중...
일치하는것 없음
TcpOmronFinsTransport.cs
이 파일의 문서화 페이지로 가기
1
using
System.Net.Sockets;
2
using
Dreamine.PLC.Abstractions.Results;
3
using
Dreamine.PLC.Omron.Fins.Options
;
4
using
Dreamine.PLC.Omron.Fins.Protocol
;
5
6
namespace
Dreamine.PLC.Omron.Fins.Transport
;
7
16
public
sealed
class
TcpOmronFinsTransport
:
IOmronFinsTransport
17
{
26
private
readonly SemaphoreSlim
_syncLock
=
new
(1, 1);
35
private
readonly
OmronFinsConnectionOptions
_options
;
44
private
TcpClient?
_tcpClient
;
53
private
NetworkStream?
_stream
;
62
private
bool
_disposed
;
63
88
public
TcpOmronFinsTransport
(
OmronFinsConnectionOptions
options)
89
{
90
_options
= options ??
throw
new
ArgumentNullException(nameof(options));
91
}
92
101
public
bool
IsConnected
=>
_tcpClient
?.Connected ==
true
&&
_stream
is not
null
;
102
143
public
async Task<PlcResult>
ConnectAsync
(CancellationToken cancellationToken =
default
)
144
{
145
await
_syncLock
.WaitAsync(cancellationToken).ConfigureAwait(
false
);
146
try
147
{
148
ThrowIfDisposed
();
149
if
(
IsConnected
)
150
{
151
return
PlcResult.Success();
152
}
153
154
await
CloseCoreAsync
().ConfigureAwait(
false
);
155
_tcpClient
=
new
TcpClient { NoDelay =
true
};
156
157
using
var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
158
timeoutCts.CancelAfter(
_options
.ConnectTimeoutMs);
159
await
_tcpClient
.ConnectAsync(
_options
.Host,
_options
.Port, timeoutCts.Token).ConfigureAwait(
false
);
160
_stream
=
_tcpClient
.GetStream();
161
return
PlcResult.Success();
162
}
163
catch
(OperationCanceledException ex)
164
{
165
await
CloseCoreAsync
().ConfigureAwait(
false
);
166
return
PlcResult.Failure(ex.Message);
167
}
168
catch
(Exception ex)
169
{
170
await
CloseCoreAsync
().ConfigureAwait(
false
);
171
return
PlcResult.Failure(ex.Message);
172
}
173
finally
174
{
175
_syncLock
.Release();
176
}
177
}
178
219
public
async Task<PlcResult>
DisconnectAsync
(CancellationToken cancellationToken =
default
)
220
{
221
await
_syncLock
.WaitAsync(cancellationToken).ConfigureAwait(
false
);
222
try
223
{
224
await
CloseCoreAsync
().ConfigureAwait(
false
);
225
return
PlcResult.Success();
226
}
227
finally
228
{
229
_syncLock
.Release();
230
}
231
}
232
305
public
async Task<PlcResult<byte[]>>
SendAndReceiveAsync
(
306
IReadOnlyList<byte> requestFrame,
307
int
receiveTimeoutMs,
308
int
retryCount,
309
CancellationToken cancellationToken =
default
)
310
{
311
ArgumentNullException.ThrowIfNull(requestFrame);
312
313
await
_syncLock
.WaitAsync(cancellationToken).ConfigureAwait(
false
);
314
try
315
{
316
ThrowIfDisposed
();
317
if
(
_stream
is
null
||
_tcpClient
is
null
|| !
_tcpClient
.Connected)
318
{
319
return
PlcResult<byte[]>.Failure(
"The FINS TCP transport is not connected."
);
320
}
321
322
var packet =
OmronFinsTcpPacket
.
Wrap
(requestFrame);
323
using
var timeoutCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
324
timeoutCts.CancelAfter(receiveTimeoutMs);
325
326
await
_stream
.WriteAsync(packet, timeoutCts.Token).ConfigureAwait(
false
);
327
await
_stream
.FlushAsync(timeoutCts.Token).ConfigureAwait(
false
);
328
329
var responsePacket = await
ReceiveFinsTcpPacketAsync
(
_stream
, timeoutCts.Token).ConfigureAwait(
false
);
330
return
PlcResult<byte[]>.Success(
OmronFinsTcpPacket
.
Extract
(responsePacket));
331
}
332
catch
(OperationCanceledException ex)
333
{
334
return
PlcResult<byte[]>.Failure(ex.Message);
335
}
336
catch
(Exception ex)
337
{
338
return
PlcResult<byte[]>.Failure(ex.Message);
339
}
340
finally
341
{
342
_syncLock
.Release();
343
}
344
}
345
370
public
async ValueTask
DisposeAsync
()
371
{
372
if
(
_disposed
)
373
{
374
return
;
375
}
376
377
await
DisconnectAsync
().ConfigureAwait(
false
);
378
_syncLock
.Dispose();
379
_disposed
=
true
;
380
GC.SuppressFinalize(
this
);
381
}
382
439
private
static
async Task<byte[]>
ReceiveFinsTcpPacketAsync
(NetworkStream stream, CancellationToken cancellationToken)
440
{
441
var header =
new
byte
[16];
442
await
ReadExactlyAsync
(stream, header, cancellationToken).ConfigureAwait(
false
);
443
444
var length =
OmronFinsEndian
.
ReadInt32
(header, 4);
445
if
(length < 8)
446
{
447
throw
new
InvalidOperationException($
"Invalid FINS/TCP packet length: {length}."
);
448
}
449
450
var bodyLength = length - 8;
451
var body =
new
byte
[bodyLength];
452
await
ReadExactlyAsync
(stream, body, cancellationToken).ConfigureAwait(
false
);
453
454
var packet =
new
byte
[header.Length + body.Length];
455
Buffer.BlockCopy(header, 0, packet, 0, header.Length);
456
Buffer.BlockCopy(body, 0, packet, header.Length, body.Length);
457
return
packet;
458
}
459
516
private
static
async Task
ReadExactlyAsync
(NetworkStream stream,
byte
[] buffer, CancellationToken cancellationToken)
517
{
518
var offset = 0;
519
while
(offset < buffer.Length)
520
{
521
var read = await stream.ReadAsync(buffer.AsMemory(offset, buffer.Length - offset), cancellationToken).ConfigureAwait(
false
);
522
if
(read == 0)
523
{
524
throw
new
IOException(
"The remote FINS endpoint closed the TCP connection."
);
525
}
526
527
offset += read;
528
}
529
}
530
547
private
async Task
CloseCoreAsync
()
548
{
549
_stream
?.Dispose();
550
_tcpClient
?.Dispose();
551
_stream
=
null
;
552
_tcpClient
=
null
;
553
await Task.CompletedTask.ConfigureAwait(
false
);
554
}
555
572
private
void
ThrowIfDisposed
()
573
{
574
ObjectDisposedException.ThrowIf(
_disposed
,
this
);
575
}
576
}
Dreamine.PLC.Omron.Fins.Options
Definition
OmronFinsConnectionOptions.cs:1
Dreamine.PLC.Omron.Fins.Protocol
Definition
OmronFinsCommand.cs:1
Dreamine.PLC.Omron.Fins.Transport
Definition
FakeOmronFinsTransport.cs:3
Dreamine.PLC.Omron.Fins.Options.OmronFinsConnectionOptions
Definition
OmronFinsConnectionOptions.cs:12
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.Transport.IOmronFinsTransport
Definition
IOmronFinsTransport.cs:14
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport._stream
NetworkStream? _stream
Definition
TcpOmronFinsTransport.cs:53
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.DisconnectAsync
async Task< PlcResult > DisconnectAsync(CancellationToken cancellationToken=default)
Definition
TcpOmronFinsTransport.cs:219
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.DisposeAsync
async ValueTask DisposeAsync()
Definition
TcpOmronFinsTransport.cs:370
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.ReadExactlyAsync
static async Task ReadExactlyAsync(NetworkStream stream, byte[] buffer, CancellationToken cancellationToken)
Definition
TcpOmronFinsTransport.cs:516
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.ThrowIfDisposed
void ThrowIfDisposed()
Definition
TcpOmronFinsTransport.cs:572
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport._disposed
bool _disposed
Definition
TcpOmronFinsTransport.cs:62
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.CloseCoreAsync
async Task CloseCoreAsync()
Definition
TcpOmronFinsTransport.cs:547
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport._tcpClient
TcpClient? _tcpClient
Definition
TcpOmronFinsTransport.cs:44
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.ConnectAsync
async Task< PlcResult > ConnectAsync(CancellationToken cancellationToken=default)
Definition
TcpOmronFinsTransport.cs:143
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport._options
readonly OmronFinsConnectionOptions _options
Definition
TcpOmronFinsTransport.cs:35
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.TcpOmronFinsTransport
TcpOmronFinsTransport(OmronFinsConnectionOptions options)
Definition
TcpOmronFinsTransport.cs:88
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.ReceiveFinsTcpPacketAsync
static async Task< byte[]> ReceiveFinsTcpPacketAsync(NetworkStream stream, CancellationToken cancellationToken)
Definition
TcpOmronFinsTransport.cs:439
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.IsConnected
bool IsConnected
Definition
TcpOmronFinsTransport.cs:101
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport._syncLock
readonly SemaphoreSlim _syncLock
Definition
TcpOmronFinsTransport.cs:26
Dreamine.PLC.Omron.Fins.Transport.TcpOmronFinsTransport.SendAndReceiveAsync
async Task< PlcResult< byte[]> > SendAndReceiveAsync(IReadOnlyList< byte > requestFrame, int receiveTimeoutMs, int retryCount, CancellationToken cancellationToken=default)
Definition
TcpOmronFinsTransport.cs:305
Transport
TcpOmronFinsTransport.cs
다음에 의해 생성됨 :
1.17.0