我使用多线程异步套接字从XDomainRequest接收数据。到目前为止,我没有接收数据的问题,但我不喜欢我目前的做法。所以我想知道是否有更好的主意。
这是我的StateObject:
public class StateObject
{
public Socket workSocket = null;
public const int BufferSize = 256;
public byte[] buffer = new byte[BufferSize];
public StringBuilder sb = new StringBuilder();
// stores total byte length which comes from XDomainRequest
public int totalReceivedBuffer = 0;
// stores byte lenght comes when each call of ReceiveCallBack
public int receivedBuffer = 0;
}
在AcceptCallBack中,我创建了StateObject:
StateObject state = new StateObject();
state.workSocket = handler;
然后我必须做一个奇怪的事情来学习总接收字节:
System.Threading.Thread.Sleep(200);
state.totalReceivedBuffer = handler.Available;
如果我不睡觉,我得到的值小于实际值。在ReceiveCallBack方法中,我收到了一小部分数据的字节长度:
int numBytesReceived = handler.EndReceive(result);
我得到来自AcceptCallBack的StateObject并将接收到的字节添加到它:
state = (StateObject)result.AsyncState;
handler = state.workSocket;
state.receivedBuffer += numBytesReceived;
然后我控制它是否等于总字节数:
if(state.receivedBuffer == state.totalReceivedBuffer)
{
// do the job
}
else
{
// Call ReceiveCallBack again
}
有更好的方法吗?
修改
我在AcceptCallBack结束时调用ReceiveCallBack:
handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state);
我的ReceiveCallBack功能在这里。我切了一些:
public static void ReceiveCallback(IAsyncResult result)
{
StateObject state = null;
Socket handler = null;
try
{
state = (StateObject)result.AsyncState;
handler = state.workSocket;
string clientIP = ((IPEndPoint)handler.RemoteEndPoint).Address.ToString();
// See how many bytes received
int numBytesReceived = handler.EndReceive(result);
if (!handler.Connected)
{
handler.Close();
return;
}
if (numBytesReceived > 0)
{
state.receivedBuffer += numBytesReceived;
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, numBytesReceived));
// Read all data line by line
string[] lines = state.sb.ToString().Split('\n');
if (state.receivedBuffer == state.totalReceivedBuffer)
{
// All data came
// do the job according to lines array
}
else
{
// continue receiving
handler.BeginReceive(state.buffer, 0, state.buffer.Length, SocketFlags.None, new AsyncCallback(ReceiveCallback), state);
}
}
}
catch (ObjectDisposedException ex)
{
// Don't care
}
catch (SocketException ex)
{
#region SocketException
if (ex.ErrorCode == 10054)
{
// HATA: "An existing connection was forcibly closed by the remote host"
Globals.ErrorLogYaz(_log, Globals.GetCurrentMethod(), "Karşı taraf işlem tamamlanmadan bağlantıyı kapattı!", ex.StackTrace);
handler.Close();
}
#endregion
}
catch (Exception ex)
{
Globals.ErrorLogYaz(_log, Globals.GetCurrentMethod(), ex.Message, ex.StackTrace);
handler.Close();
}
}
答案 0 :(得分:0)
从连接中读取数据的方法是实际调用Receive
并检查您获得的字节数。没有办法预测会有多少人来。 Available
是现在可用的数据量。接收方怎么可能知道发送者将来会发送多少钱?它无法知道。
在循环中调用Receive
,直到它返回0(连接关闭)或直到你通过其他方式知道所有字节都被接收为止。
由于你似乎是一个带套接字的初学者,并且似乎没有理由使用异步,你可能应该使用同步IO。它简单得多。