目前是接收一次处理一次,当对方发动数据大于我定义的长度1024后,后面的数据就错了;
想修改为全部接收完再做处理,应该怎么修改???
代码如下:
public void ReceivedCallback(IAsyncResult ar)
{
try
{
StateObjectClass state = (StateObjectClass)ar.AsyncState;
Socket handler = state.workSocket;
if (handler == null) return;
if (handler.Connected != true)
{
handler.Close();
//客户端退出
//...
return;
}
int bytesRead = handler.EndReceive(ar);
state.bytesRead = bytesRead;
if (bytesRead != 0)
{
//CommAction 方法内容: a.截取所发指令的前面几个字节分析是不是要求的指令
//里面有一个 state.packetBuff = state.buffer.Take(bytesRead).ToArray();的操作
state = CommAction(state);
if (state.CommandString != "")
//处理指令
//回调
handler.BeginReceive(state.buffer, 0, StateObjectClass.BufferSize, 0,
new AsyncCallback(ReceivedCallback),
state);
}
else
{
handler.Close(); //客户端退出
//...
}
}
catch (SocketException ex)
{
if (ex.ErrorCode == 10054) //客户端关闭连接
{
//...
}
}
catch (Exception ex)
{
//...
}
}
------解决思路----------------------
要么把你的1024改成足够大,能够一次性接收到全部的数据不要截断
要么定义好通信协议,以什么开始,以什么结束,或者先发个较短的包过来告诉后面的包总长度
否则你怎么知道什么时候算接收完了?
------解决思路----------------------
如果你想把多次收到的数据先拼接到一起
一样还是需要另一个足够大的数组来存放这个数据啊
------解决思路----------------------
你的Socket是长连接还是短连接?
如果是长连接,你没办法确定报文有没有传输完,只能根据报文包长度进行截取。
短连接的话,根据你的通讯协议,定义适当长度的缓存数组。
------解决思路----------------------
不定义大的你就必须知道长度,然后循环接收,直到长度满足,或者对方发送完成会关闭通道,不然你无法知道什么时候才算收完
------解决思路----------------------
你原先代码中:
if?(state.CommandString?!=?"")
//处理指令
这个处理指令部分修改下,不要直接处理指令,而是先将接收到的内容存到队列中,例如
全局定义一个List<byte[]> buffers = new List<byte[]>();
之后if (bytesRead != 0)时
if?(state.CommandString?!=?"" && buffers.Count>0)
{
//把buffers里面原有的数组列表拼接处理为一个命令,并执行
buffers.Clear(); //清空buffers
}
buffers.Add(state.packetBuff);//写新命令数据进buffers队列。
else时
if?(buffers.Count>0)
{
//把buffers里面原有的数组列表拼接处理为一个命令,并执行
buffers.Clear(); //清空buffers
}
------解决思路----------------------
我的疏忽,没考虑多线程的情况,你可以修改StateObjectClass类的定义,将那个List<byte[]> buffers作为一个属性定义在类内部,通过state传递到下次操作中累计即可。