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#