消息之前要通过对我的一个应用程序,我用一段简单的代码,一个TCP连接发送数据:缓冲区被覆盖,可以读取
public void Send(byte[] message)
{
if (socket != null)
{
if (stream != null)
{
stream.Write(message, 0, message.Length);
if (receiveThread == null)
{
StartReceiver();
}
}
}
}
插座是TcpClient
类的一个实例,并且该流是关联的流实例。 StartReceiver()
启动一个线程,正如该方法所暗示的那样,它接收发送给应用程序的数据。
要接收的数据,我使用:
private void ReceiveLoop()
{
DataReceivedStruct drs;
try
{
for (; ;)
{
if (stream != null)
{
drs = new DataReceivedStruct();
drs.stream = stream;
drs.waitHandle = are;
stream.BeginRead(readBuffer, 0, readBuffer.Length, DataReceived, drs);
Console.WriteLine("Waiting to be allowed to continue");
are.WaitOne();
Console.WriteLine("Allowed, continuing loop");
}
else
{
Thread.Sleep(5);
}
}
}
catch (SocketException e)
{
DispatchRaiseException(e);
}
catch (Exception e)
{
DispatchRaiseException(e);
}
}
再次,所用的流是TcpClient
类对象的上述流实例。 readBuffer对象是byte[1024]
。给BeginRead
回调看起来是这样的:
private void DataReceived(IAsyncResult result)
{
DataReceivedStruct drs = (DataReceivedStruct)result.AsyncState;
NetworkStream used = drs.stream;
AutoResetEvent handle = drs.waitHandle;
used.EndRead(result);
DispatchRaiseReceived(readBuffer);
Console.WriteLine("Signalling allowance of continue for loop");
handle.Set();
}
它结束的流读取动作和传中readBuffer数据集。
这在原则上起作用。我可以发送和接收来自应用程序的数据。应用程序的接收端只有一个问题。向应用程序发送消息时,调用BeginRead
函数,之后回调触发并结束与EndRead
的读取操作,并传递数据以供进一步处理。这适用于一次一条消息。但在第一条消息触发BeginRead
后直接发送另一条消息时,它会变得更有趣。接下来会发生的第一条消息的EndRead
还没有发生,所以第一条消息的数据被第二条消息覆盖,导致数据不正确。
我应该停止使用BeginRead
/EndRead
,只是使用阻止Read
操作来接收数据?还是有可能锁定流与BeginRead
/EndRead
,所以第二个消息不会收到,直到第一个消息处理?
而不是使用共享缓冲区('readBuffer'),在'DataReceivedStruct'中声明它 – 2012-02-17 10:34:20
无关紧要,因为流仍会覆盖第二条消息。 – ThaMe90 2012-02-17 10:40:02
不,既然你把它传递给'BeginRead' – 2012-02-17 10:47:41