问题
About the Code
I am using EasyModbus Nuget
in C# Window Form Application. I am trying to fetch the changed Holding Register's Address Value through RTU(Real Time Update) using ModbusServer
.
Below code connect to server.
void Connect() {
ModbusClient client = null;
client = new ModbusClient("IP Address", 502);
client.Connect();
}
Below code fetches the value of address given below Holding Register.
client.ReadHoldingRegisters(10001, 1);
So far, everything works perfectly.
I was reading about reading about Real Time Updates in EasyModbus. I found this link that can send the changed value of holding register automatically to the even handler.
Now, I have below code:
void Connect() {
ModbusServer ser = new ModbusServer();
ser.Port = Convert.ToInt32(Settings.Default.Port);
ser.Listen();
ser.HoldingRegistersChanged += Ser_HoldingRegistersChanged;
ModbusClient client = null;
client = new ModbusClient("IP Address", 502);
client.Connect();
}
private void Ser_HoldingRegistersChanged(int register, int numberOfRegisters)
{
}
When I run it, I get below error.
Only one usage of each socket address (protocol/network address/port) is normally permitted
This error is occurring because I added the ModbusServer code.
Can you please suggest why this is happening?
回答1:
Your problem isn't so serious and your main problem in this line
ser.Listen();
because your previous server socket is still in bound.
let's take a looks when a listen socket is in bound ?
obvious reason is when your listening socket send/receive packets but in rare conditions it happens when OS is NOT in ideal condition(100 % cpu usage and etc) then Releasing server socket might takes a minute to be released. in this condition when you run your server again the exception
Only one usage of each socket address (protocol/network address/port) is normally permitted
happens.because , as i said before the previous server socket was not released yet.
Solution is
using different ports for different server sockets
or
use only one server socket which is initiated only once and check if it's connected or not.
// create the socket
public static Socket listenSocket = new Socket(AddressFamily.InterNetwork,
SocketType.Stream,
ProtocolType.Tcp);
// bind the listening socket to the port
IPAddress hostIP = (Dns.Resolve(IPAddress.Any.ToString())).AddressList[0];
IPEndPoint ep = new IPEndPoint(hostIP, port);
if(!listenSocket.IsBound){
listenSocket.Bind(ep);
// start listening
listenSocket.Listen(backlog);
}
// connect client
ModbusClient client = null;
client = new ModbusClient(hostIP , port);
client.Connect();
回答2:
It seems you already have a server on the port and you try to add one more. Try the code below:
public partial class Form1 : Form
{
private int register = 0;
private readonly int port = 502;
private readonly List<ModbusServer> servers = new List<ModbusServer>();
private readonly List<ModbusClient> clients = new List<ModbusClient>();
public Form1()
{
InitializeComponent();
AppDomain.CurrentDomain.FirstChanceException +=
(sender, e) => MessageBox.Show(e.Exception.Message);
}
private void Foo(object sender, ThreadExceptionEventArgs e)
{
MessageBox.Show(e.Exception.Message);
}
private void Ser_HoldingRegistersChanged(int register, int numberOfRegisters) =>
MessageBox.Show($"register: {register}, numberOfRegisters: {numberOfRegisters}");
private void AddServer_Click(object sender, EventArgs e) =>
AddServerMethod();
private void AddClient_Click(object sender, EventArgs e) =>
AddClientMethod();
private void AddServerMethod()
{
var server = new ModbusServer { Port = port };
server.Listen();
server.HoldingRegistersChanged += Ser_HoldingRegistersChanged;
servers.Add(server);
MessageBox.Show("Server added.");
server.holdingRegisters[0] = 11; // register is changed, but no event is fired
}
private void AddClientMethod()
{
var client = new ModbusClient("127.0.0.1", port);
client.Connect();
clients.Add(client);
MessageBox.Show("Client added.");
client.WriteSingleRegister(register++, 11); // event is fired
}
}
If you click AddServer
more than once you get the error you described. Btw, if you click AddClient
before AddServer
you get another error. Add one server and then add any number of clients. Each client writes a holding register and related event is fired with a message like this:
来源:https://stackoverflow.com/questions/57984190/issue-while-writing-modbusclient-and-modbusserver-together