Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / New Users / June 2006

Tip: Looking for answers? Try searching our database.

UDP Comms and Connection Reset Problem

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jonas Hei - 21 Jun 2006 14:43 GMT
Our application does UDP communications using the Socket class in
System.Net.Sockets.

The Socket.EndReceiveFrom() often throws a SocketException (ErrorCode:
10054, WSAECONNRESET, "An existing connection was forcibly closed by the
remote host").

This seems to be a common problem affecting a lot of people and it
appears that this happens due to 'ICMP Port unreachable' responses to
the UDP messages already sent out. KB263823
(http://support.microsoft.com/kb/263823/en-us) explains the problem.

Looking at the above KB I expect to get SocketExceptions with
WSAECONNRESET during Socket.EndReceiveFrom(). And they do happen often.

But sometimes I also get same exception during
Socket.BeginReceiveFrom(). Why?

What is the best way to fix this problem?

Should we be using Socket.IOControl() to set SIO_UDP_CONNRESET to false?
(Our application runs on Windows Server 2003)

Or should we be catching SocketExceptions and ignoring the WSAECONNRESET
errors?
Markus Stoeger - 21 Jun 2006 19:40 GMT
Hi Jonas,

> Looking at the above KB I expect to get SocketExceptions with
> WSAECONNRESET during Socket.EndReceiveFrom(). And they do happen often.
>
> But sometimes I also get same exception during
> Socket.BeginReceiveFrom(). Why?

I had the same problem just a few weeks ago. And I hate it for throwing
in BeginReceiveFrom!! My whole code was full of try/catches because of that.

> What is the best way to fix this problem?

Since I found out about the IOControl call with SIO_UDP_CONNRESET the
problem is gone (no more silly exceptions that I don't care about with
UDP!). I've successfully used that on W2K and XP so far.

Simply disabling that behaviour should definitelly be cheaper than
catching exceptions -- catching wastes lots of cpu cycles.

hth,
Max
Jonas Hei - 21 Jun 2006 22:51 GMT
> Since I found out about the IOControl call with SIO_UDP_CONNRESET the
> problem is gone (no more silly exceptions that I don't care about with
> UDP!). I've successfully used that on W2K and XP so far.

Max, thanks a lot for the solution.

By the way how did you set SIO_UDP_CONNRESET to FALSE?

I have tried doing as per Zupancic's suggestion
(http://blog.devstone.com/aaron/archive/2005/02/20.aspx):
  // 0x9800000C == 2440136844 (uint) == -174483042 (int) == 0x9800000C
  const int SIO_UDP_CONNRESET = -174483042;
  byte[] inValue = new byte[] { 0, 0, 0, 0 };     // == false
  byte[] outValue = new byte[] { 0, 0, 0, 0 };    // initialize to 0
  _socket.IOControl(SIO_UDP_CONNRESET, inValue, outValue);

But it does not work for me - it throws a SocketException (An invalid
argument was supplied).

The code illustrated in http://thedotnet.com/nntp/8375/showpost.aspx 
does not work for me either.

By the way I am currently on .NET1.1/VS2003.
Even if I had been on .NET2.0 I guess the new method
Socket.IOControl(IOControlCode, Byte[], Byte[]) wouldn't have helped
me...I couldn't find the equivalent for SIO_UDP_CONNRESET in
IOControlCode enum
(http://msdn2.microsoft.com/en-us/library/system.net.sockets.iocontrolcode.aspx)
Jonas Hei - 22 Jun 2006 18:48 GMT
> I have tried doing as per Zupancic's suggestion
> (http://blog.devstone.com/aaron/archive/2005/02/20.aspx):
[quoted text clipped - 6 lines]
> But it does not work for me - it throws a SocketException (An invalid
> argument was supplied).

Zupancic was just telling us that it is kind of lame to copy and paste
code snippets from anywhere without giving them a serious thought first.

So after being lame for a few hours (give or take a few more hours), I
finally gave some thought to it and luckily managed to solve the problem:
instead of
// 0x9800000C == 2440136844 (uint) == -174483042 (int) == 0x9800000C
we need
// 0x9800000C == 2550136844 (uint) == -1744830452 (int) == 0x9800000C

so this snippet seems to work:

   const int SIO_UDP_CONNRESET = -1744830452;
   byte[] inValue = new byte[] { 0, 0, 0, 0 };     // == false
   byte[] outValue = new byte[] { 0, 0, 0, 0 };    // initialize to 0
   _socket.IOControl(SIO_UDP_CONNRESET, inValue, outValue);
Markus Stoeger - 22 Jun 2006 20:39 GMT
> Zupancic was just telling us that it is kind of lame to copy and paste
> code snippets from anywhere without giving them a serious thought first.
[quoted text clipped - 12 lines]
>    byte[] outValue = new byte[] { 0, 0, 0, 0 };    // initialize to 0
>    _socket.IOControl(SIO_UDP_CONNRESET, inValue, outValue);

I used the following code... looks clean to me. I don't think it's
necessary to pass arrays of 4 bytes. 1 byte is enough. And the second
array can be null because we don't need the return values:

uint IOC_IN = 0x80000000;
uint IOC_VENDOR = 0x18000000;
uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;

s.IOControl((int)SIO_UDP_CONNRESET, new byte[] {Convert.ToByte(false)},
null);

Max

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.