Connect multiple meter in multi threaded environment

There seems to be a problem if you call GXNet.Open() in different threads at the same time. In case of two threads, the second thread will throw the following exception:

A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied.

The exception occurs on Socket.BeginReceive(...), but the problem is caused by the async connect. If I exchange the async connect

// Create a SocketAsyncEventArgs object to be used in the connection request
SocketAsyncEventArgs socketEventArg = new SocketAsyncEventArgs();
socketEventArg.RemoteEndPoint = ep;
SocketError err = 0;
try
{
// Inline event handler for the Completed event.
// Note: This event handler was implemented inline in order to make this method self-contained.
socketEventArg.Completed += new EventHandler(delegate(object s, SocketAsyncEventArgs e)
{
err = e.SocketError;
m_clientDone.Set();
});

// Sets the state of the event to nonsignaled, causing threads to block
m_clientDone.Reset();

// Make an asynchronous Connect request over the socket
m_Socket.ConnectAsync(socketEventArg);

// Block the UI thread for a maximum of TIMEOUT_MILLISECONDS milliseconds.
// If no response comes back within this time then proceed
m_clientDone.WaitOne(TIMEOUT_MILLISECONDS);
if (err != 0)
{
throw new SocketException((int)err);
}
}
finally
{
socketEventArg.Dispose();
}

with the sync connect

m_Socket.Connect(ep);

it works as expected. It's possibly a problem of the .NET Framework and not directly a problem of the Gurux library. The sync connect has, of course, the disadventage, that no timeout will occure. But an async connect makes no sense in a async environment. May be, there should be an option to connect synchronously.

I've created a demo project that addresses the above problem. Please contact me by mail if anybody is interested in.

kurumi's picture

Hi,

You are right. We have not tested using our communication libraries from different threads. Usually there is not need for this.

If you need this functionality. Let me know and we will add thread safety to Media components.

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
Hermiankatu 6-8 H 33720 TAMPERE, FINLAND
Phone: +358 3 265 1244
Home page: http://www.gurux.org

Hi,

Thanks for your replay, I didn't saw it and also didn't get an E-Mail notification that you wrote a reply. How ever, we use your library to read multiple meter (>100) every Minute, so we have to split up the execution in different threads. This causes the above Problem, if multiple threads connect at the same time. If I edit the source code to connect synchronously I have no Problem, but it would be perfect, if you can add thread safety to the media components.

best regards,
Stier

kurumi's picture

Hi,

We have added thread safety to all media components.
Basic idea is this.

lock (gxNet1.SyncRoot)
{
gxNet1.Open();
...
Do something...
...
gxNet1.Close();
}

You can read more how to use network media here:

http://www.gurux.fi/index.php?q=Gurux.Net

Get latest versions from Gurux.Common and media components from GitHub or Nuget.org.

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
Hermiankatu 6-8 H 33720 TAMPERE, FINLAND
Phone: +358 3 265 1244
Home page: http://www.gurux.org

Hello,

I need develop a similar multithread system and I get the same error message with the latest version. I try the SyncLock method to make it work, but this sometimes work, sometimes not (throwing the same SocketException). I use the software to read data from SL7000 and ACE6000 meters with the Quartz scheduler. Can you help me please avoid this exception or can you send me please the demo project? Thank you! I try the following variations:

'Define Media object: S.Media
SyncLock (S.Media.SyncRoot)
Using client As New AVRDlmsClient(S)
'...
' Call InitializeConnection
SynLock Media.SyncRoot
Media.Open() <- The error throwing here randomly
End SyncLock
'...
End Using
End SyncLock

SZL

kurumi's picture

Hi,

Please, create own thread if you have question. You did not tell error, but is it possible that you have two threads that try to connect same IP address?

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
Hermiankatu 6-8 H 33720 TAMPERE, FINLAND
Phone: +358 3 265 1244
Home page: http://www.gurux.org

Hi,

Sorry, I use this post because my problem is same than in the first comment. The error message is the same too: "A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied". Yes some of my threads connect to the same IP (with different port). But I test it with different IP addresses too, and the same error message throwing sometimes. Thanks!

SZL

kurumi's picture

Hi,

Are you making multiple instances from the component or are you using one and share it between threads?

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
Hermiankatu 6-8 H 33720 TAMPERE, FINLAND
Phone: +358 3 265 1244
Home page: http://www.gurux.org

I open new client in every thread (one per device). I have similar connection parameters:

IP: 100.100.100.210, Port: 4001, Physical Address: 17
IP: 100.100.100.210, Port: 4002, Physical Address: 18
IP: 100.100.100.210, Port: 4003, Physical Address: 19
IP: 100.100.100.211, Port: 4001, Physical Address: 14
IP: 100.100.100.211, Port: 4002, Physical Address: 15
IP: 100.100.100.211, Port: 4003, Physical Address: 16
...
(46 devices)

SZL

kurumi's picture

Hi,

Are you also creating new media component for each thread?

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
Hermiankatu 6-8 H 33720 TAMPERE, FINLAND
Phone: +358 3 265 1244
Home page: http://www.gurux.org

Hi,

Yes, because all Quartz job running on an isolated place (in a new class instance). Every object is new.
I tried with the .NET async/await Taks-s too, this produces the same error message.

Thanks!

SZL

kurumi's picture

Hi,

Usually this error is received because there is not server listening. Are you using Moxa?

BR,
Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
Hermiankatu 6-8 H 33720 TAMPERE, FINLAND
Phone: +358 3 265 1244
Home page: http://www.gurux.org

Hi,

Yes, we use Moxa.

SZL

kurumi's picture

Hi,

I'm not sure if this helps you, but are all connections start at the same time?
If connection fails, put small random delay and try to connect again.
There was one project where our Moxa was not able to handle connections if they are established at the same time. I don't know if this helps you, but you can try.

BR,

Mikko

________________________________________
Mikko Kurunsaari
Gurux Ltd
Hermiankatu 6-8 H 33720 TAMPERE, FINLAND
Phone: +358 3 265 1244
Home page: http://www.gurux.org

Hi,

Thanks for the idea! Yes, all connections start at the same time but I can set delay.
Currently if a SocketException throwing the application try the communication again after 3 sec. In this case sometimes I get OutOfMemoryException and some Unknown Error, but this is not problem, the software try it again. The data logging seems good when I check it in the database.
This version works well, but the device communication is non-stop. :) I have 46 devices and I need read it every 1 minutes. So far, I have not found a better solution.

BR,

SZL