C# Socket在连接目标主机成功后的瞬间接、发操作必须要加锁;
2012-11-17 12:43
351 查看
如题:
C# Socket在连接目标主机成功后的瞬间接、发操作必须要加锁;
经过100~300次的调试次数,该问题,在Win7不会出现,在XP,100%出现,可能也是Socket调用系统底层,的问题,这时看的就是操作系统底层的一些稳定性了;
从而可以看到,Win7底层是比XP稳定的;
因为在Win7,C# Socket在连接目标主机成功后的瞬间接、发操作可以 不加锁操作;
而在Xp如果不加锁操作,则100%出现:
异常:
System.Net.Sockets.SocketException (0x80004005): 由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
但在XP下,如果加断点调试的话,是100%不报上面这个异常,you know why?
类似这样的问题,很多都是因为异步操作过快,所以就在这些操作比较容易出现,异步问题加个锁操作即可;
就有点像:原子操作一样;
还有别一种方法,Poll方法,可以参数官方MSDN说明:
http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.poll(v=vs.80).aspx
使用方法 :
使用lock()+poll()方法,是我目前觉得最稳定,可靠的;
C# Socket在连接目标主机成功后的瞬间接、发操作必须要加锁;
经过100~300次的调试次数,该问题,在Win7不会出现,在XP,100%出现,可能也是Socket调用系统底层,的问题,这时看的就是操作系统底层的一些稳定性了;
从而可以看到,Win7底层是比XP稳定的;
因为在Win7,C# Socket在连接目标主机成功后的瞬间接、发操作可以 不加锁操作;
而在Xp如果不加锁操作,则100%出现:
异常:
System.Net.Sockets.SocketException (0x80004005): 由于套接字没有连接并且(当使用一个 sendto 调用发送数据报套接字时)没有提供地址,发送或接收数据的请求没有被接受。
但在XP下,如果加断点调试的话,是100%不报上面这个异常,you know why?
类似这样的问题,很多都是因为异步操作过快,所以就在这些操作比较容易出现,异步问题加个锁操作即可;
private readonly object locker=new object(); public void BeginConnect() { //其它代码; lock(locker) { //执行连接的代码体 } //其它代码; } public void BeginSend() { //其它代码; lock(locker) { //执行发送的代码体 } //其它代码; } public void BeginRecieve() { //其它代码; lock(locker) { //执行接收的代码体 } //其它代码; }
就有点像:原子操作一样;
还有别一种方法,Poll方法,可以参数官方MSDN说明:
http://msdn.microsoft.com/zh-cn/library/system.net.sockets.socket.poll(v=vs.80).aspx
使用方法 :
private void BeginAsyncConnect(IAsyncResult ia) { lock (_receiveLocker) { try { Socket socket = ia.AsyncState as Socket; while (!(_socket.Poll(1000 * 500, SelectMode.SelectWrite))) //当然这里你可以自己写个微秒的累加判断,到一定时间长度时就抛个超时异常 { OnPoll(this, new ClientEvent(_socket, "Poll") { target = Interlocked.Add(ref _pollCount, 1) }); } socket.EndConnect(ia); if (Connected != null) { Connected(this, new ClientEvent(socket)); } } catch (Exception er) { Close("异步链接异常,断开链接,原因:\r\n" + er.ToString()); } } }
public void StartReceiverServer() { lock (_receiveLocker) { if (!_socket.Connected) throw new Exception("_socket未链接无法执行StartServer"); while (!(_socket.Poll(1000 * 500, SelectMode.SelectWrite))) { OnPoll(this, new ClientEvent(_socket, "Poll") { target = Interlocked.Add(ref _pollCount, 1) }); } _socket.BeginReceive( _stateObject.BufferData, 0, ClientStateObj.BUFFERSIZE, SocketFlags.None, new AsyncCallback(BeginAsyncReceive_PackageHeaderFixSize), _stateObject); } }
使用lock()+poll()方法,是我目前觉得最稳定,可靠的;
相关文章推荐
- SVN checkout失败提示:由于目标主机积极拒绝,无法连接的问题
- 加载驱动成功com.microsoft.sqlserver.jdbc.SQLServerException: 不支持此服务器版本。目标服务器必须是 SQL Server 2000 或更高版本。链接失败
- ORA-12545 因目标主机或对象不存在,连接失败
- linux VNC连接失败:套接字操作尝试一个无法连接的主机(10065)
- “ORA-12545: 因目标主机或对象不存在,连接失败”怎么办?
- 无法转移操作主机角色:不能连接FSMO盒
- oracle-ORA-12545:因目标主机或对象不存在,连接失败的解决办法
- oracle监听多台主机配置,用pl/sql连接操作多个数据库详解
- “ORA-12545: 因目标主机或对象不存在,连接失败”怎么办?
- ORA-12545: 因目标主机或对象不存在, 连接失败
- VMware vCenter启动虚拟机"在主机的当前连接状况下不允许执行该操作"
- Java语言实现简单FTP软件------>连接管理模块的实现:主机与服务器之间的连接与关闭操作(八)
- 【转载】SQLServer 2012 已成功与服务器建立连接,但是在登录前的握手期间发生错误。 (provider: SSL Provider, error: 0 - 等待的操作过时
- outlook 2003配置连接exchange server 2010报错——无法完成此操作。 与 Microsoft Exchange Server 的连接不可用。 Outlook 必须联机或连接才可完成该操作
- 已成功与服务器建立连接,但是在登录前的握手期间发生错误。 (provider: SSL Provider, error: 0 - 等待的操作过时)
- 使用vncviewer成功连接red hat linux server 连接失败:套接字操作尝试一个...
- SQLServer 2012 已成功与服务器建立连接,但是在登录前的握手期间发生错误。 (provider: SSL Provider, error: 0 - 等待的操作过时。
- vcenter : 在主机的当前连接状况下不允许执行该操作
- 连接excel执行Insert Into语句出现“操作必须使用一个可更新的查询”的解决
- ora-12545:因目标主机或对象不存在,连接失败的解决办法