I am developing an application in which Lets says 50-60 Modbus supporting devices (Slaves) are connected to a Com Port which are communicating with my application in request response mechanism.
I want after every 15 min. request should be sent to every meter and response to be received from meter one by one.
communicating with multiple slave (Modbus protocol based)
For this i am making the use of System.Timers.timer to call the method lets say ReadAllSlave() after every 15 min.
In ReadAllSlave() i have used For loop to send the request and to receive response and using thread.sleep to maintain the delay..! but it seems that its not working and loop is executing in damn wired way.
private void StartPoll()
{
double txtSampleRate = 15 * 60 * 1000;
timer.Interval = txtSampleRate;
timer.AutoReset = true;
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
for(int index = 0; index<meterCount; Index++)
{
//Sending request to connected meter..
mb.SendFc3(m_slaveID[0], m_startRegAdd[0], m_noOfReg[0], ref value_meter);
if (mb.modbusStatus == "Read successful")
{
//Some code for writing the values in SQL Express database
}
//Wait for some time so that will not get timeout error for the next
//request..
Thread.Sleep(10000);
}
}
Can any one please suggest me the best approach to implement the same.
Thanks in advance.
It looks like your problem is a trivial one... You're always interrogating the same slave !
"index" is never used in your code...
What about something like this :
mb.SendFc3(m_slaveID[index], m_startRegAdd[index], m_noOfReg[index], ref value_meter);
Related
I am sending messages from various places on my 10G network. I am using a Pub/Sub pattern.
The messages I send are serialized using zeroFormatter and have length of approx 270 bytes.
Once I start to send over 150K message per sec, I notice the subscriber starting to miss messages.
How do I work out what the limits I can expect to be able to send are?
EDIT 1:
I am sending just under 1 billion bits/sec, which is a 10th of the capacity of my network. After this point I start to miss messages. Would this be due to CPU issues? Neither sender or receiver seem highly utilized...
private void BackgroundProcess()
{
int msgSeqNum = 0;
using (var server = new PublisherSocket())
{
server.Options.SendHighWatermark = 1000;
server.Bind(Connection);
var address = Key;
FastTickData fastTickData;
while (true)
{
if (O.TryTake(out fastTickData, 60000))
{
msgSeqNum++;
server.SendMoreFrame(address).SendMoreFrame(msgSeqNum.ToString()).SendMoreFrame(DateTime.UtcNow.ToString("yyyyMMddTHHmmssffffff")).SendFrame(ZeroFormatterSerializer.Serialize(fastTickData));
}
}
}
}
I have a client type application that is receiving packets from remote server.
Now and then it so happens that for some reason server disconnects me.
Sometimes there are some problems on my end ISP drops internet etc.
I have been trying to catch those exceptions and goog-ling for an answer but at the end every one
points to "make a timer and check periodically for received packets."
Now i have a function that is receiving all incoming traffic.
This function is executed every time packet is received.
Now my idea is to create a function that will create timer with let say 50 seconds time out.
This function will reset timer to 0 each time packet is received and restart it.
If timer reach 50 seconds it will throw an error "disconnected!" and some logic will follow
how to reconnect.
Now main problem i have is ... i can not "pause" my main packet receiving function.
I have tried to make it in another thread but program keep recreating new threads , killing threads by ID is a bad practice and i haven't gone down that road ... yet.
Is this a how i should handle my problem or someone has a better idea?
Below is my packet receive function.
public void OnReceive()
{
try
{
recv_pack = locSec.TrIncom();
if (recv_pack != null)
{
foreach (Packet packet in recv_pack)
{
byte[] packet_bytes = packet.GetBytes();
PacketHandler.HandlePacket(packet, locSec);
//here i would check for packet receive with timer
//CheckDisconnect();
}
}
}
catch()
{}
}
So far i have come up with this:
public bool CheckDisconnect()
{
bool KeepGoing = true;
for(int i = 0 ; i <= 50 && KeepGoing; i++ )
{
Thead.Sleep(1000);
if(i == 50)
{
KeepGoing = false;
Console.WriteLine("Disconnected!");
// ... starting reconnect procedure
}
}
}
Not sure if i understand completely, but if those two functions are in the same thread, can't you just make a global variable that controls the OnReceive() function and set it to false in your CheckDisconnect() function?
I'm currently getting started on a socket programming project for a University network planning course. I'm also doing a Programming class in which we are learning C# so I thought it appropriate to use C# to complete this assignment.
The assignment is to create a simple Server-Client connection and have data sent between them. That is not too much of a problem, I've read a few tutorials and watched a few videos and I think I know what I'm doing. That part which has me a little confused is this:
"2) Every second, the server sends Client a command to seek measurement data, e.g., through a single letter "R" or "r" (request). (timing control is required here)."
This has me confused, What exactly is timing control? And how can I go about implementing it.
Thanks in advance.
EDIT: I found an "example" of timing control, but it is in the C/C++, Do I need to do something liek this?
/* Step 5.2: Send and Receive Data in loops */
time_old = getTime();
iterationStep = 1;
for (;;)
{
recvStatus = recv(TCPClient, recvBuffer,128,0);
if(recvStatus == 0)
break;
else if(recvStatus == SOCKET_ERROR)
{
printf("Failed in recv(): %d\n",WSAGetLastError());
break;
}
recvBuffer[recvStatus] = 0x00; /* '\0' */
time_new = getTime();
time_interval = time_new - time_old;
time_old = time_new;
printf("Step = %5d; Time Interval = %8.6f; Received String: %s\n", iterationStep,time_interval,recvBuffer);
iterationStep++;
}
/* if "EXIT" received, terminate the program */
if (!strcmp(recvBuffer,"EXIT"))
{
printf("TCP Server ready to terminate.");
break;
}
}
EDIT 2:
Im trying now to use this method but am having some trouble. I have created this method:
private static void SendRequest(Object source, ElapsedEventArgs e) {
byte[] buffer = Encoding.Default.GetBytes("WAAAAT");
acc.Send(buffer, 0, buffer.Length, 0);
}
But as you can see, I cannot use the "acc" socket because I can set it as a parameter. I tried to but then I get a lot of errors when calling the method, any advice?
It sounds like you will need to use the "System.Timers.Timer" class to execute your "send request" function every second.
Example:
static void Main()
{
// Create a timer with a one second interval.
aTimer = new System.Timers.Timer(1000);
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += SendRequest;
aTimer.Enabled = true;
}
private static void SendRequest(Object source, ElapsedEventArgs e)
{
// maybe end existing request if not completed?
// send next request
}
Whether you time out(cancel) any existing requests before starting a new one will depend on your requirements as it is also possible to have many requests running in parallel. If you do need to kill a request, you can do so by disposing the System.Net.Sockets.Socket that initiated the connection attempt (you will need to handle any errors thrown by the Socket.Connect).
Timing control sounds like a mechanism to insure that the requests are fired 1 sec apart and that if a request doesn't complete in a timely fashion to terminate that request and fire the next one.
Take a scenario
Request 1 fires at point 0
After 1 sec request 1 hasn't received an answer but request 2 needs to fire.
You probably need to implement a timeout system based on a clock.
hello all i have this issue , and i am stuck with it so any help will be greatly appreciated
i have to build a socket chat (client Server) module and i have done almost 80% of the work but now i am stuck , Scenario is that i have a server app and clients connect to it now if say 4 clients are connected to server each of them can communicate to each other , one client will send message and server will receive that message and will pass it along ,this is working very fine but when 2 or more clients send a message to 3rd client at the same time than i can not get one message and client get disconnected i know i have to build up a queue structure but i am not getting succeeded in it here
here is my code structure
StartReceive(SocketAsyncEventArgs) ->
First of all i call this method to start listening for incoming messages
and when i got one message i check if it is completed Sync or Async
and after this there is an io completed listener which is called every time one receive opertaion is completed and in that io completed method i do call processReceive method which is used to process received chunks
so finally my code structure is like this
StartReceive-> IO Completed -> ProcessReceive
i have designed the structure so that every client will have a Receive SOCKETASYNCEVENTAGRS
object and a Send SOCKETASYNCEVENTAGRS at server side and i do maintain a pool for this
so each client receives and sends data through its own SOCKETASYNCEVENTAGRS object
i want a scenario such that if two or more clients send messages to 3rd client than 3rd client should not receive all messages at the same time instead it should have a queue structure and it should receive one message at a time and same for send operation
here is some of my code
private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs)
{
DataHoldingUserToken receiveSendToken = (DataHoldingUserToken)receiveSendEventArgs.UserToken;
receiveSendEventArgs.SetBuffer(receiveSendToken.bufferOffsetReceive, this.socketListenerSettings.BufferSize);
bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
if (!willRaiseEvent)
{
ProcessReceive(receiveSendEventArgs);
}
}
This is IO Completed
void IO_Completed(object sender, SocketAsyncEventArgs e)
{
DataHoldingUserToken receiveSendToken = (DataHoldingUserToken)e.UserToken;
switch (e.LastOperation)
{
case SocketAsyncOperation.Receive:
ProcessReceive(e);
break;
default:
}
}
and this is my StartReceive with Queue implemented but it is not working
Queue rec = new Queue();
bool IsExecuted = true;
private void StartReceive(SocketAsyncEventArgs receiveSendEventArgs)
{
if (IsExecuted)
{
DataHoldingUserToken receiveSendToken = (DataHoldingUserToken)receiveSendEventArgs.UserToken;
rec.Enqueue(receiveSendToken);
}
try
{
receiveSendEventArgs.SetBuffer(receiveSendToken.bufferOffsetReceive, this.socketListenerSettings.BufferSize);
bool willRaiseEvent = receiveSendEventArgs.AcceptSocket.ReceiveAsync(receiveSendEventArgs);
if (!willRaiseEvent)
{
ProcessReceive(receiveSendEventArgs);
}
rec.Dequeue();
IsExecuted = true;
}
catch
{
IsExecuted = false;
StartReceive(receiveSendEventArgs);
}
}
looking for a decent help or some good direction
I'm not sure if this is the root cause of your problem but it seems to me that you are running out of DataHoldingUserToken at some time because you are never doing anything with the objects you dequeue, hence you are throwing it away.
Also note that it is recommended to use the generic form of the Queue class for non-trivial object. That would be System.Collections.Generic.Queue<DataHoldingUserToken>.
I have an application that pings every possible IP on your local subnet in order to compile a list of responsive IP addresses. Currently it pings all 255 one at a time. Is it possible to convert this app to use multiple threads to increase the speed by pinging more than one at a time? I am new to the concept of multiple threads and figure this would be a good way to learn(as long as it's possible of course).
also, any stylistic improvements you can educate me on would also be helpful.
thanks ahead of time
Here is the current pinging method in a backgroundWorker1_DoWork event.
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
count = 0;
for (int i = 1; i < 255; i++)
{
Ping ping = new Ping();
PingReply pingreply = ping.Send(IPAddress.Parse(locip[0] + "." + locip[1] + "." + locip[2] + "." + i));
count += 1;
if (pingreply.Status == IPStatus.Success)
{
status = "o";
repAddress = pingreply.Address.ToString(); ;
repRoundtrip = pingreply.RoundtripTime.ToString();
repTTL = pingreply.Options.Ttl.ToString();
repBuffer = pingreply.Buffer.Length.ToString();
string[] lineBuffer = { status, repAddress, repRoundtrip, repTTL, repBuffer };
ipList.Rows.Add(lineBuffer);
}
progressBar.Invoke(new MethodInvoker(UpdateProgressBarByOne));
progressStatus.Text = ("Pinging IP " + count + " of 254");
}
button1.Enabled = true;
progressBar.Invoke(new MethodInvoker(ResetProgressBar));
}
It looks like Ping has a SendAsync function. This post (I know its vb, but just to get an idea) has an example. In summary, just change your Send to SendAsync and listen for the PingCompleted event
Well my advice is to look into your concurrency points.
Firstly you will hit a bug with any access to windows forms objects off the thread. i.e your access to button1 WILL throw an MDA in debug, and might crash at runtime randomly. You have to use a delegate and invoke the method back on the main thread using a pattern like this.
this.Invoke(delgatetomyupdatermethod)
Secondly, your time is spent in the ping itself. So I would recommend writing a threadsafe list (just write a method with a lock on it
private object locker = new object();
private void InsertIntoList(string linebuffer)
{
lock(locker)
{
ipList.Rows.Add(linebuffer);
}
}
I would recommend using the .Net threadpool to run your method instead to ping a given IP.
To do this write a function that will take in the IP to ping and to update the list with your result, then call it by queueing up items on the threadpool. Indeed if you pass in an object with a ManualResetEvent you can even write your code to say
System.Threading.WaitHandle[] waits = new System.Threading.WaitHandle[255];
//initialise the list of these and create the objects to ping.
foreach (var obj in mylistofobjectvalues)
{
System.Threading.Threadpool.QueueUserWorkItem(method, obj);
}
System.Threading.WaitHandle.WaitAll(waits);
where method is the ping method, obj contains an object with the manualresetevent and information your method needs to ping it's target.
Each time your waithandle completes you can update your state. With some more effort on your GUI you could even have the system working asynchronously, so that your gui is updated on each response, not just at the end.