2010-01-09 69 views
3

我是编程新手,我对异步套接字编程感到困惑。C#异步套接字BeginSend EndReceive

例如,假设我有两个BeginSend s,一个接一个。第一个发送一百万个字符,第二个发送只有64个字符。

由于异步性不会在第一个完成之前完成第二个BeginSend

如果是的话我怎么能告诉接收到的数据在EndRecieve,属于哪个消息?

回答

7

你真的不应该两次调用BeginSend。 我认为如果发生这种情况,你最终会看到抛出的异常。

您必须在调用另一个BeginSend之前调用EndSend。这通常在回调函数中完成。

请查看MSDN上的示例Using an Asynchronous Client Socket。在回调中调用EndSend,然后设置一个名为“sendDone”的ManualResetEvent。这是线程间通信的一种形式,其中回调会向主线程发送异步发送已完成的信号。这样可以让你的程序确定下一部分数据。从你的主线程

  • 呼叫BeginSend发送第1,000,000字节
  • 你的主线程可以检查一个信号量或类似ManualResetEvent的东西触发它发送下一个64个字节。您的其他选项是使用队列来发送数据
  • 当数据完成发送时,您传递给BeginSend的回调将被调用。
  • 在此回调中,您将调用EndSend。按照这个设置ManualResetEvent,或者想要使用什么样的线程间触发器。

我记得曾经做过的最简单的选项是调用BeginSend来获取第一部分数据的回调中的下一条数据。

例如

int NumBytesSent; // member variable containing how many bytes you have sent so far 
string Message; // Message to send that is large 

当你调用BeginSend,在经过了一大块说100个字节(挑选更高效的传输数量较多,但不是太大)由100 下发送和增量NumBytesSend,在你的回调先前的发送完成后,您可以检查NumBytesSent < Message.Length,然后是否发送下一个消息块。

这是如何发送一个文件,您一次发送一堆字节,并只是不断发送文件的块,直到它全部发送。

我强烈建议制作一个简单的客户端/服务器来执行类似于通过连接发送完整文件的操作。同时在网上查看MSDN文档和许多其他的例子。

获取有关这个良好的抓地力会帮助你与很多其他的C#主题为异步方式运行(或使用委托/回调)是很常见的.NET

+0

+1调用下一个BeginSend,建议先建立简单的建议。 –

+1

感谢马克,这是我一直建立我的网络代码的方式。 我已经做了很多次这样的事情,但总是从一个通用的简单起点开始,然后从那里开始工作。 – Fuzz

+0

有人可以解释它们的含义:它假设一个名为connectDone的全局ManualResetEvent。 – Eidenai

1

BeginSend method包括参数AsyncCallback callback。如果你使用两个不同的回调函数,你可以先看看哪一个回调函数完成。

但是,如果您试图在同一连接上发送这两个消息,您将遇到问题。在发送第二条消息之前,您应该等到第一条消息完全发送完毕。

+0

是IM发送两个消息到相同的地址/端口。 – iTEgg

+0

我认为发送可能会起作用,但我怀疑这些消息会变成交织和不可解析的。 –

+0

这个问题。我如何避免这种情况?它可以做到,因为像mirc这样的应用程序一直处理这些类型的问题。我想知道我该如何执行它? – iTEgg