1.问题的引出:
这几天在做有关socket方面的编程,由于不是很懂所以出现的一些问题。在这里写下希望能和大家分享!如果那里有不对的欢迎支持。一起学习!异步接收数据时我的以前的做法是:将取得的数据和自己发送的数据协议相比较,如数据的包头正确并数据的长度达到要求的话就认为是接收到的数据是正确的了!大概代码如下:
private void ReceiveCallback(IAsyncResult ar)
{
try
{
//
StateObject state = ar.AsyncState as StateObject;
//读取数据
int bytesRead = mSocket.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(UTF8Encoding.UTF8.GetString(state.buffer, 0, bytesRead));
string sb = state.sb.ToString();
if (sb.Substring(sb.Length - 1, 1) == EndChar)
{
//接收完成
//激发事件
if (onStreamData != null)
onStreamData(mID, UTF8Encoding.UTF8.GetBytes(sb));
if (onStringData != null)
onStringData(mID, sb);
//
state = new StateObject();
state.workSocket = mSocket;
}
// Get the rest of the data.
mSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
{
try
{
//
StateObject state = ar.AsyncState as StateObject;
//读取数据
int bytesRead = mSocket.EndReceive(ar);
if (bytesRead > 0)
{
state.sb.Append(UTF8Encoding.UTF8.GetString(state.buffer, 0, bytesRead));
string sb = state.sb.ToString();
if (sb.Substring(sb.Length - 1, 1) == EndChar)
{
//接收完成
//激发事件
if (onStreamData != null)
onStreamData(mID, UTF8Encoding.UTF8.GetBytes(sb));
if (onStringData != null)
onStringData(mID, sb);
//
state = new StateObject();
state.workSocket = mSocket;
}
// Get the rest of the data.
mSocket.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
}
这样的写法,一般的情况下不会出现问题,但如果我先在服务器端的接收数据的方法内打上断点,让他的代码一直阻塞着(或者用sleep,让接收数据的线程不能已接收到数据就能马上处理)在客户端一直发送数据(10次以上)这是再让服务器接收数据的方法继续执行,可以发现服务器端并没有接收到客户端发送的所有的数据!
问题的解决:<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
建立一个队列,将服务器端接收到得数据放到这个队列里。在另一个线程中循环读取该队列,对接收到得数据一个一个比特的解析,直到达到符合的条件为止!修改的代码如下:
private void ReceiveCallback(IAsyncResult ar)
{
try
{
//Thread.Sleep(10000);
//
byte[] state = ar.AsyncState as byte[];
//读取数据
int bytesRead = mSocket.EndReceive(ar);
if (bytesRead > 0)
{
byte[] receive = new byte[bytesRead];
Array.Copy(state, 0, receive, 0, bytesRead);
lock ((this.queMess as ICollection).SyncRoot)
{
this.queMess.Enqueue(receive);
}
if (threadMess == null)
{
threadMess = new Thread(new ThreadStart(CycleReadQueue));
threadMess.IsBackground = true;
threadMess.Start();
}
if (threadMess.ThreadState == ThreadState.Stopped)
{
threadMess = new Thread(new ThreadStart(CycleReadQueue));
threadMess.IsBackground = true;
threadMess.Start();
}
mSocket.BeginReceive(state, 0, BUFF_SIZE, 0, new AsyncCallback(ReceiveCallback), state);
}
}
{
try
{
//Thread.Sleep(10000);
//
byte[] state = ar.AsyncState as byte[];
//读取数据
int bytesRead = mSocket.EndReceive(ar);
if (bytesRead > 0)
{
byte[] receive = new byte[bytesRead];
Array.Copy(state, 0, receive, 0, bytesRead);
lock ((this.queMess as ICollection).SyncRoot)
{
this.queMess.Enqueue(receive);
}
if (threadMess == null)
{
threadMess = new Thread(new ThreadStart(CycleReadQueue));
threadMess.IsBackground = true;
threadMess.Start();
}
if (threadMess.ThreadState == ThreadState.Stopped)
{
threadMess = new Thread(new ThreadStart(CycleReadQueue));
threadMess.IsBackground = true;
threadMess.Start();
}
mSocket.BeginReceive(state, 0, BUFF_SIZE, 0, new AsyncCallback(ReceiveCallback), state);
}
}
private void CycleReadQueue()
{
byte[] receive = new byte[BUFF_SIZE];
int nPositon = 0;
int nTimes = 1;
while (queMess.Count > 0)
{
byte[] mess = queMess.Dequeue();
foreach (byte c in mess)
{
if (nPositon >= BUFF_SIZE * nTimes)
{
nTimes++;
Array.Resize(ref receive, BUFF_SIZE * nTimes);
}
Array.Copy(new byte[] { c }, 0, receive, nPositon, 1);
nPositon++;
string str = UTF8Encoding.UTF8.GetString(receive, 0, nPositon);
//string str = sb.ToString();
if (str.Substring(str.Length - 1, 1) == EndChar)
{
//接收完成
//激发事件
if (onStreamData != null)
onStreamData(mID, UTF8Encoding.UTF8.GetBytes(str));
if (onStringData != null)
onStringData(mID, str);
receive = new byte[BUFF_SIZE];
nPositon = 0;
nTimes = 1;
sb = new StringBuilder();
}
}
}
}
{
byte[] receive = new byte[BUFF_SIZE];
int nPositon = 0;
int nTimes = 1;
while (queMess.Count > 0)
{
byte[] mess = queMess.Dequeue();
foreach (byte c in mess)
{
if (nPositon >= BUFF_SIZE * nTimes)
{
nTimes++;
Array.Resize(ref receive, BUFF_SIZE * nTimes);
}
Array.Copy(new byte[] { c }, 0, receive, nPositon, 1);
nPositon++;
string str = UTF8Encoding.UTF8.GetString(receive, 0, nPositon);
//string str = sb.ToString();
if (str.Substring(str.Length - 1, 1) == EndChar)
{
//接收完成
//激发事件
if (onStreamData != null)
onStreamData(mID, UTF8Encoding.UTF8.GetBytes(str));
if (onStringData != null)
onStringData(mID, str);
receive = new byte[BUFF_SIZE];
nPositon = 0;
nTimes = 1;
sb = new StringBuilder();
}
}
}
}
转载于:https://blog.51cto.com/zwxhyy/304151