Jump to content

  • Log In with Google      Sign In   
  • Create Account

Morxeton

Member Since 07 Jan 2009
Offline Last Active May 14 2013 07:35 AM

Posts I've Made

In Topic: C# .NET 4.0/4.5 UDP send issue

20 March 2013 - 03:39 PM

These args are supposed to be reusable

They are re-usable, but only after the send request that used the arguments has completed (or returned an error!)

If you re-use a SocketAsyncEventArgs before the first operation that it's used on completes, all kinds of bad behavior may occur, including you not sending the data you think you're sending.

If you keep one buffer per SocketAsyncEventArgs and keep track of completed send args in a queue where you can re-use them when next sending (and create a new buffer/args pair if the queue is empty) then your system will work correctly.

 

Right, I was implementing it wrong for sending but correctly for receiving.  I have a class called SocketState that contains the socket and other important info pertaining to the connection.  At the time the SocketState is created, args for both sending and receiving are retrieved from a Stack and assigned to that SocketState for the duration of its existence.  They're reset and returned to the Stack on disposal.  I used a dedicated buffer for receiving but for sending I was calling SetBuffer and changed the underlying buffer on each send call by setting the buffer to the byte array of data to be sent.  It was done in a thread safe context using locking and a queuing mechanism so the next send would NOT execute until after the previous send's callback had completed.  Surprisingly enough, this flawed implementation was NOT an issue on .NET 3.5 and was NOT an issue for TCP on .NET 4.0/4.5.  Therefore, this is how it managed to elude me for a couple days... smile.png

 

Once I assigned a dedicated buffer for sending, and used Buffer.BlockCopy to copy the byte array to be sent to the buffer, it worked flawlessly.


In Topic: C# .NET 4.0/4.5 UDP send issue

19 March 2013 - 04:56 PM

I figured this out. This issue is happening because the underlying buffer on the variable m_ClientSendArgs is constantly being changed using SetBuffer:

 

byte[] buffer = m_ClientSendQueue.Dequeue();

m_ClientSendArgs.SetBuffer(buffer, 0, buffer.Length); 

 

When I assigned a static buffer to it and used Buffer.BlockCopy, the issue went away:

 

byte[] buffer = m_ClientSendQueue.Dequeue();

Buffer.BlockCopy(buffer, 0, m_ClientSendBuffer, 0, buffer.Length);

m_ClientSendArgs.SetBuffer(0, buffer.Length); 

 

So I've been implementing it wrong all along. It's strange that it wasn't an issue on .NET 3.5, or an issue for TCP on .NET 4.0/4.5.


In Topic: C# .NET 4.0/4.5 UDP send issue

19 March 2013 - 02:20 PM

I found out what's causing this error. If I create a new SocketAsyncEventArgs before each send, I can't reproduce the error. If I reuse the same SocketAsyncEventArgs, I eventually run into this error. I verified that the args are used in a thread safe context and the only modification to it is the SetBuffer for each send call. These args are supposed to be reusable, and in fact for receiving I have no problems reusing them there. I also don't have any problems reusing them in .NET 3.5 for sending. Very strange that in 4.0 and 4.5 I can't reuse the args for sending. Sounds like a bug...

 

I should also note that this is NOT a problem for TCP on .NET 4.0 and 4.5. In fact, the TCP implementation I built is identical to the UDP implementation (as far as the structure of reusing the args and queueing data to be sent using locking for thread safety).


In Topic: C# .NET 4.0/4.5 UDP send issue

18 March 2013 - 04:18 PM

I also posted this question to StackOverflow:  http://stackoverflow.com/questions/15485999/c-sharp-net-4-0-4-5-udp-send-issue

 

Something I noticed (copied from my comments on StackOverflow):

 

I noticed that when it's being called from the UI is where it seems to happen. If I click the "ClientSnd" button then hold enter down to spam it, this issue occurs. If I create a while loop which sends the buffer 10,000 times, and click the "ClientSnd" button once (where the new while loop is located), it works fine. If I click the button again and send the buffer another 10,000 times, it fails.

 

Here's a screenshot from my sample project demoing the issue:

UDPTest-SocketErrorAddressFamilyNotSuppo


In Topic: C# "Memory leak" issue

06 February 2010 - 12:37 PM

Quote:
Original post by TheUnbeliever
For future reference, using source tags will make your post much easier to read as it provides a scrolling, syntax-highlighted box.

Thanks for the info. I wrapped [code=auto:0] tags around it and noticed it didn't work. I wasn't sure what the tags were for it.

PARTNERS