当前位置:编程学习 > C#/ASP.NET >>

C# 中无法立即完成一个非阻挡性套接字操作,急救

当服务器端有返回值的时候是没有问题的,但接收完数据后
 int nBytes = socketChannel.Receive( receiveBuff);
就抛出“无法立即完成一个非阻挡性套接字操作”错误,不知道为什么,请大侠们指点指点。
代码如下:
      /**
     * 提供客户操作的若干方法
     */
    abstract public class VOClient : VONIO
    {
    /** 通道 */
        public System.Net.Sockets.Socket socketChannel    = null;
        /** 运行模式 */
        protected String                 mode             = "offline";
     
    /** 接收数据缓冲区,默认为256k */
    private byte[]                   receiveBuff      = new byte[ 2<<11 ] ;
    /** 可以还原的最大对象,4M */
    private static int  objectBufSize   = 2 << 21;
    /** 最大对象的数据数据块存储对象**/
    private byte[]  objectBuf       = new byte[objectBufSize];
    /** count代表objectBuf中现有的(剩下的)字节数**/
    private int      count       = 0;
    /** 判断是否需要关闭通道**/
    private bool      done       = false;
    /** 判断当前数据处理是一次处理还是多次出来**/
    private bool      runOnceMore   = false;
    /** 字节数组长度**/
    private int  dlen    = -1;

    /**
     * 向服务器通道发送数据
         * @param arg0: 操作命令
         * @param arg1: 易做图作数据
     */
    public VOFuture send(int arg0, byte[] arg1)
    {
    if( arg1 == null)
    return new VOFuture( this, false);
    VOFuture future = new VOFuture( this, false);
    try
    {
    /** 数据长度 */
    int i =  arg1.Length;
    byte[] len = new byte[4];
    len[0] = (byte) (i >> 24);
    len[1] = (byte) (i >> 16);
    len[2] = (byte) (i >> 8);
    len[3] = (byte) (i);
                socketChannel.Send(len);
                socketChannel.Send(arg1);

    future.setSucceeded( true);
    future.setCommand( arg0);
    }
    catch(System.IO.IOException e)
    {
    future.setSucceeded( false);
                com.verygis.veryobject.error.VODebug.exportErrorInfo(e.Message);
    }
    
    return future;
    }
    
    /**
         * 注册客户端, 生成一socket
         * @param arg0 服务器地址
         * @param arg1 服务器端口号
         */
    public bool login(String  arg0, int arg1)
        {
    try
    {
                System.Net.IPAddress ip = System.Net.IPAddress.Parse(arg0);
                System.Net.IPEndPoint ipe = new System.Net.IPEndPoint(ip, arg1);
    /** 创建服务于此客户端的Socket */
                socketChannel = new System.Net.Sockets.Socket(System.Net.Sockets.AddressFamily.InterNetwork, 
                    System.Net.Sockets.SocketType.Stream, System.Net.Sockets.ProtocolType.Tcp);
                socketChannel.Connect(ipe);
    socketChannel.Blocking = false;
    
    /** 此线程启动 */ 
    setClientModeOn();
            }
            catch (ArgumentNullException e)
            {
                return false;
            }
    catch(System.Net.Sockets.SocketException e)
    {
    return false;
    }
    catch(System.IO.IOException e)
    {
    return false;
    }
    
    return true;
    }
    
    /**
     * 关闭通道
     */
    protected void closeChannel()
    {
    try
    {
    if( !done )
    done = true;
    
    if( socketChannel != null)
    {
    socketChannel.Close();
    socketChannel = null;
    }
    
    objectBuf = null;
    }
    catch(System.IO.IOException e)
    {
    com.verygis.veryobject.error.VODebug.exportErrorInfo(e.Message);
    }
    }
--------------------编程问答-------------------- public void run() 
    {
    if( done )
    done = false;

    while( !done )
    {
    try
    {
    if( socketChannel != null )
    {
    socketChannel.Blocking = false;
    /** 读取数据 */
                        System.Array.Clear(receiveBuff, 0, receiveBuff.Length);
                        this.waitonenano();
    int nBytes = socketChannel.Receive( receiveBuff);
    while( nBytes > 0 || runOnceMore) 
    {
                        /** 将数据全部转移存入缓存 */
    copyData ( receiveBuff, count, nBytes);
    /** count代表objectBuf中现有的(剩下的)字节数 */
                        count += nBytes;                                  
                        while( count >= 4)
                        {
                            if( dlen < 0)
                            {
                                dlen = calcLen(objectBuf);      
                            }

                 while ( count < dlen +4 )
                 {
                                    System.Array.Clear(receiveBuff, 0, receiveBuff.Length);
                 nBytes = socketChannel.Receive(receiveBuff);
                 /** 将数据全部转移存入缓存 */
                 copyData ( receiveBuff,  count, nBytes);
                 count += nBytes;
                 }
                             
                            if( dlen > 0 /** 有数据 */
                             && (count - 4) >= dlen /** 数据够用 */)
                            {
    try 
    {
             int comm = com.verygis.veryobject.pdu.VOPDUObjectCreator.getCommand( objectBuf, 4);
             firePropertyChange( comm + "", 4, objectBuf);
    } 
    catch(Exception e) 
    {
    }
                                    /**  重置,去掉已经使用的字节数,安全拷贝 */
                                    System.Array.Copy(objectBuf, dlen + 4, objectBuf, 0, count - 4 - dlen);
                                    count = count - 4 - dlen;
                                    dlen = -1;
                                    if (count >= 4)/** 处理最后一次 */
                                    {
                                        runOnceMore = true;
                                    }
                                    else
                                        runOnceMore = false;    
                            }
                        }
                        /** 继续读取数据 */                    
                            System.Array.Clear(receiveBuff, 0, receiveBuff.Length);
                        if ( count >= 4)
                         nBytes = socketChannel.Receive(receiveBuff);
                        else
                            {
                                nBytes = 0;
                             }
                    }
    if( nBytes == 0 )
    {
    waitonenano();
    }
    if( nBytes == -1 )
    {
    socketChannel.Close();
    socketChannel = null;
    }
    }
    }
    catch(System.IO.IOException e)
    {
    try
    {
    socketChannel.Close();
    socketChannel = null;
    setClientModeOff();
    }
    catch(System.IO.IOException e1)
    {
    }
    }
    } 
    }  
    
    private void copyData ( byte[] src_receiveBuff,   
    int count, int nBytes )
    {
    bool bExtend = false;
    while( count + nBytes > objectBufSize )
    {
    bExtend = true;
    objectBufSize *= 2;
    }
    if( bExtend )
    {
    byte[] tmp_buf = new byte[objectBufSize];
    System.Array.Copy( objectBuf, 0, tmp_buf, 0, count);
    objectBuf = null;
    objectBuf = tmp_buf;
    }
            System.Array.Copy(src_receiveBuff,0, objectBuf,count, nBytes);
    }
    
    abstract public void setClientModeOn();
    abstract public void setClientModeOff();
    /**
         * 返回客户端状态
         */
    public String getClientMode()
        {
            return mode;
        }
        /**
         * 获取当前连接的System.Net.Sockets.Socket
         */
    public System.Net.Sockets.Socket getSocket()
        {
         return socketChannel;
        }
    }
--------------------编程问答-------------------- 我最怕看这些多又长的代码
楼主可以精简一下 把出错的那部分注释一下好让别人容易看懂一点 --------------------编程问答-------------------- 同意ls~ --------------------编程问答-------------------- 我现在也遇到这个问题,请问你以前是怎么解决的,谢谢 --------------------编程问答-------------------- 无语啊
我也遇到这样的问题了 --------------------编程问答-------------------- 期待高手、牛人啊!
补充:.NET技术 ,  C#
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,