public async void ServerRespectsMaxClientConnectionLimit()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer()
                  {
                      MaxConnections = 2
                  };

            server.Start(endpoint);

            // Act
            var client1 = new ModbusTcpClient();
            var client2 = new ModbusTcpClient();
            var client3 = new ModbusTcpClient();

            await Task.Run(() =>
            {
                client1.Connect(endpoint);
                client1.WriteSingleRegister(0, 2, 3);

                client2.Connect(endpoint);
                client2.WriteSingleRegister(0, 2, 3);

                client3.Connect(endpoint);

                try
                {
                    client3.WriteSingleRegister(0, 2, 3);
                    throw new Exception("Modbus TCP server accepts too many clients.");
                }

                // Windows
                catch (IOException) { }

                // Linux
                catch (InvalidOperationException) { }

                server.MaxConnections = 3;

                client3.Connect(endpoint);
                client3.WriteSingleRegister(0, 2, 3);
            });

            // Assert
        }
Пример #2
0
        public void CanReadMaximumNumberOfRegisters()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            var server = new ModbusTcpServer();

            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            client.ReadHoldingRegisters <ushort>(0, 0, 125);
            client.ReadInputRegisters <ushort>(0, 0, 125);
        }
Пример #3
0
        public async void ServerHandlesMultipleClients()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            // Act
            var clients = Enumerable.Range(0, 20).Select(index => new ModbusTcpClient()).ToList();

            var tasks = clients.Select((client, index) =>
            {
                var data = Enumerable.Range(0, 20).Select(i => (float)i).ToArray();

                client.Connect(endpoint);
                _logger.WriteLine($"Client {index}: Connected.");

                return(Task.Run(async() =>
                {
                    _logger.WriteLine($"Client {index}: Task started.");

                    for (int i = 0; i < 10; i++)
                    {
                        client.ReadHoldingRegisters <short>(0, 0, 100);
                        _logger.WriteLine($"Client {index}: ReadHoldingRegisters({i})");
                        await Task.Delay(50);
                        client.WriteMultipleRegisters(0, 0, data);
                        _logger.WriteLine($"Client {index}: WriteMultipleRegisters({i})");
                        await Task.Delay(50);
                        client.ReadCoils(0, 0, 25);
                        _logger.WriteLine($"Client {index}: ReadCoils({i})");
                        await Task.Delay(50);
                        client.ReadInputRegisters <float>(0, 0, 20);
                        _logger.WriteLine($"Client {index}: ReadInputRegisters({i})");
                        await Task.Delay(50);
                    }

                    client.Disconnect();
                }));
            }).ToList();

            await Task.WhenAll(tasks);

            // Assert
        }
Пример #4
0
        public void ThrowsWhenWritingTooManyRegisters()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            Action action = () => client.WriteMultipleRegisters <ushort>(0, 0, new ushort[124]);

            // Assert
            Assert.Throws <ModbusException>(action);
        }
Пример #5
0
        public void ThrowsIfZeroBytesAreRequested()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            Action action = () => client.ReadHoldingRegisters <byte>(0, 0, 0);

            // Assert
            Assert.Throws <ModbusException>(action);
        }
Пример #6
0
        public void ThrowsIfOddNumberOfBytesIsRequested()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            Action action = () => client.ReadHoldingRegisters <byte>(0, 0, 3);

            // Assert

            Assert.Throws <ArgumentOutOfRangeException>(action);
        }
Пример #7
0
        public void ThrowsWhenReadingTooManyRegisters()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            Action action1 = () => client.ReadHoldingRegisters <ushort>(0, 0, 126);
            Action action2 = () => client.ReadInputRegisters <ushort>(0, 0, 126);

            // Assert
            Assert.Throws <ModbusException>(action1);
            Assert.Throws <ModbusException>(action2);
        }
Пример #8
0
        public void ArraySizeIsCorrectForBooleanInput()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            var actual = client.ReadHoldingRegisters <bool>(0, 0, 10).ToArray().Count();

            // Assert
            var expected = 10;

            Assert.True(actual == expected);
        }
Пример #9
0
        public async Task FC023Test()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            void AsyncWorkaround()
            {
                var buffer = server.GetHoldingRegisterBuffer <float>();

                buffer[6] = 65.455F;
                buffer[7] = 24;
                buffer[8] = 25;
            }

            lock (server.Lock)
            {
                AsyncWorkaround();
            }

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            var actual1 = await client.ReadWriteMultipleRegistersAsync <float, float>(0, 2, 10, 12, new float[] { 1.211F });

            // Assert
            var expected = new float[] { 0, 0, 0, 0, 0, 1.211F, 24, 25, 0, 0 };

            Assert.True(expected.SequenceEqual(actual1.ToArray()));

            lock (server.Lock)
            {
                var actual2 = server.GetHoldingRegisterBuffer <float>().Slice(1, 10).ToArray();
                Assert.True(expected.SequenceEqual(actual2));
            }
        }
Пример #10
0
        public async void ServerWorksWithExternalTcpClient()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();
            var listener = new TcpListener(endpoint);

            using var server = new ModbusTcpServer();
            var client = new ModbusTcpClient();

            var expected = new double[] { 0.1, 0.2, 0.3, 0.4, 0.5 };

            double[] actual = null;

            // Act
            listener.Start();

            var clientTask = Task.Run(() =>
            {
                client.Connect(endpoint);

                actual = client
                         .ReadWriteMultipleRegisters <double, double>(0, 0, 5, 0, expected)
                         .ToArray();

                client.Disconnect();
            });

            var serverTask = Task.Run(() =>
            {
                var tcpClient = listener.AcceptTcpClient();
                server.Start(tcpClient);
            });

            await clientTask;

            // Assert
            Assert.True(actual.SequenceEqual(expected));
        }
Пример #11
0
        public void BigEndianWritePerformanceTest()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var buffer = server.GetHoldingRegisters();

            // Act
            var sw = Stopwatch.StartNew();

            for (int i = 0; i < 1_000_000; i++)
            {
                buffer.SetBigEndian(address: 1, 12334234.0);
            }

            // Assert
            var elapsed = sw.Elapsed;

            _logger.WriteLine($"Time per 1000 write operations: {elapsed.TotalMilliseconds / 1000} ms");
        }
Пример #12
0
        public void FC16Test()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint);

            // Act
            client.WriteMultipleRegisters(0, 2, _array);

            // Assert
            var expected = _array;

            lock (server.Lock)
            {
                var actual = server.GetHoldingRegisterBuffer <float>().Slice(1, 10);
                Assert.True(expected.SequenceEqual(actual.ToArray()));
            }
        }
Пример #13
0
        public void HandlesBigEndian()
        {
            // Arrange
            var endpoint = EndpointSource.GetNext();

            using var server = new ModbusTcpServer();
            server.Start(endpoint);

            var client = new ModbusTcpClient();

            client.Connect(endpoint, ModbusEndianness.BigEndian);

            // Act
            client.WriteMultipleRegisters(0, 0, new int[] { 0x20302020, 0x40101010, 0x11220000 });

            // Assert
            var expected = new int[] { 0x20203020, 0x10101040, 0x00002211 };

            lock (server.Lock)
            {
                var actual = server.GetHoldingRegisterBuffer <int>().Slice(0, 3);
                Assert.True(expected.SequenceEqual(actual.ToArray()));
            }
        }