UDP错误10054:远程主机强迫关闭了一个现有的连接

UDP错误10054:远程主机强迫关闭了一个现有的连接

原文地址:http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx

在公司一项目的UDP消息服务开发中时不时的会遇到这样一个问题:在UDP通信过程中,如果客户端中途断开,服务器会收到一个SocketException,错误ID为10054,描述是“远程主机强迫关闭了一个现有的连接”,紧接着的事就可怕了,UDP服务终止监听,所有客户端都受到了影响。也就是说一个客户端引起的异常导致了整个系统的崩溃。这个问题可是太严重了。

地球人都知道,UDP是无连接的,怎么会出现这个异常呢?百度了一圈,发现有这个问题的现象还不少,可就是没有一个有效的回复。再GOOGLE一圈,有点眉目了。找到了一个微软的解释和一个DOTNET的解决方法:

微软的解释:http://support.microsoft.com/kb/263823

DOTNET的处理方法:http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx

不过处理方法似乎对参数的设置不太正确:    byte[] optionInValue = { Convert.ToByte(true) };     byte[] optionOutValue;

按照这样设置还是会抛出该异常。    首先,根据微软的解释,optionInValue 传入的应该是false,而不是true;     其次,根据微软的解释,optionOutValue应该是一个DWORD值,不应不赋值,或设为null。

根据以上两点,将以上两句改为:    byte[] optionInValue = { Convert.ToByte(false) };     byte[] optionOutValue = new byte[4];

经过测试,模拟500个用户进行登录、收发消息、注销、异常退出、再连接,均没有再抛出该异常。服务表现稳定。

在UDP通信过程中,如果客户端中途断开,服务器会收到一个SocketException,错误ID为10054,描述是“远程主机强迫关闭了一个现有的连接”,紧接着的事就可怕了,UDP服务终止监听,所有客户端都受到了影响。也就是说一个客户端引起的异常导致了整个系统的崩溃。

找了好几天了。终于找到了解决办法。

在初始化对象后设置属性如下:

uint IOC_IN = 0x80000000;    uint IOC_VENDOR = 0x18000000;     uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;     ClientSocket.IOControl((int)SIO_UDP_CONNRESET, new byte[] {Convert.ToByte(false)}, null);

Socket.IOControl 方法 (IOControlCode, Byte[], Byte[])

使用 IOControlCode 枚举指定控制代码,为 Socket 设置低级操作模式。

参数
ioControlCode

一个 IOControlCode 值,它指定要执行的操作的控制代码。

optionInValue

Byte 类型的数组,包含操作要求的输入数据。

optionOutValue

Byte 类型的数组,包含由操作返回的输出数据。

返回值

optionOutValue 参数中的字节数。

UDP错误10054:远程主机强迫关闭了一个现有的连接 异常

异常类型    条件

SocketException

试图访问套接字时发生错误。有关更多信息,请参见备注部分。

ObjectDisposedException

Socket 已关闭。

InvalidOperationException

试图不使用 Blocking 属性更改阻止模式。

UDP错误10054:远程主机强迫关闭了一个现有的连接 备注

此方法提供对 Socket 类的当前实例所基于的操作系统 Socket 的低级访问。有关更多信息,请参见 MSDN Library 中的 WSAIoctl 文档。

本人体会:

再做通信项目中无意中遇到了这个问题,记得上学的时候老师说过UDP是无连接的,但是在项目中遇到了这个远程主机强制关闭现有连接的错误,搞得一头雾水,什么也不用说,马上google一下,发现很多朋友都有遇到了这个问题,最后还是看到了原作者的这篇文章后解决了问题,呵呵,再次转载过来,希望帮助所有遇到这个问题的朋友快速的解决问题。

原文地址:http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx

在公司一项目的UDP消息服务开发中时不时的会遇到这样一个问题:在UDP通信过程中,如果客户端中途断开,服务器会收到一个SocketException,错误ID为10054,描述是“远程主机强迫关闭了一个现有的连接”,紧接着的事就可怕了,UDP服务终止监听,所有客户端都受到了影响。也就是说一个客户端引起的异常导致了整个系统的崩溃。这个问题可是太严重了。

地球人都知道,UDP是无连接的,怎么会出现这个异常呢?百度了一圈,发现有这个问题的现象还不少,可就是没有一个有效的回复。再GOOGLE一圈,有点眉目了。找到了一个微软的解释和一个DOTNET的解决方法:

微软的解释:http://support.microsoft.com/kb/263823

DOTNET的处理方法:http://www.devnewsgroups.net/group/microsoft.public.dotnet.framework/topic1887.aspx

不过处理方法似乎对参数的设置不太正确:    byte[] optionInValue = { Convert.ToByte(true) };     byte[] optionOutValue;

按照这样设置还是会抛出该异常。    首先,根据微软的解释,optionInValue 传入的应该是false,而不是true;     其次,根据微软的解释,optionOutValue应该是一个DWORD值,不应不赋值,或设为null。

根据以上两点,将以上两句改为:    byte[] optionInValue = { Convert.ToByte(false) };     byte[] optionOutValue = new byte[4];

经过测试,模拟500个用户进行登录、收发消息、注销、异常退出、再连接,均没有再抛出该异常。服务表现稳定。

在UDP通信过程中,如果客户端中途断开,服务器会收到一个SocketException,错误ID为10054,描述是“远程主机强迫关闭了一个现有的连接”,紧接着的事就可怕了,UDP服务终止监听,所有客户端都受到了影响。也就是说一个客户端引起的异常导致了整个系统的崩溃。

找了好几天了。终于找到了解决办法。

在初始化对象后设置属性如下:

uint IOC_IN = 0x80000000;    uint IOC_VENDOR = 0x18000000;     uint SIO_UDP_CONNRESET = IOC_IN | IOC_VENDOR | 12;     ClientSocket.IOControl((int)SIO_UDP_CONNRESET, new byte[] {Convert.ToByte(false)}, null);

Socket.IOControl 方法 (IOControlCode, Byte[], Byte[])

使用 IOControlCode 枚举指定控制代码,为 Socket 设置低级操作模式。

参数
ioControlCode

一个 IOControlCode 值,它指定要执行的操作的控制代码。

optionInValue

Byte 类型的数组,包含操作要求的输入数据。

optionOutValue

Byte 类型的数组,包含由操作返回的输出数据。

返回值

optionOutValue 参数中的字节数。

UDP错误10054:远程主机强迫关闭了一个现有的连接 异常

异常类型    条件

SocketException

试图访问套接字时发生错误。有关更多信息,请参见备注部分。

ObjectDisposedException

Socket 已关闭。

InvalidOperationException

试图不使用 Blocking 属性更改阻止模式。

UDP错误10054:远程主机强迫关闭了一个现有的连接 备注

此方法提供对 Socket 类的当前实例所基于的操作系统 Socket 的低级访问。有关更多信息,请参见 MSDN Library 中的 WSAIoctl 文档。

本人体会:

再做通信项目中无意中遇到了这个问题,记得上学的时候老师说过UDP是无连接的,但是在项目中遇到了这个远程主机强制关闭现有连接的错误,搞得一头雾水,什么也不用说,马上google一下,发现很多朋友都有遇到了这个问题,最后还是看到了原作者的这篇文章后解决了问题,呵呵,再次转载过来,希望帮助所有遇到这个问题的朋友快速的解决问题。