async Socket.EndReceive如何知道它读取的字节数?异步套接字如何完成读取?

时间:2014-05-14 09:10:44

标签: c# sockets asynchronous asyncsocket

我有这段代码

_socket.BeginReceive(
        _buffer, 
        0, 
        _buffer.Length, 
        SocketFlags.None, 
        _asyncCallback, 
        sSocketName);

**with**
_buffer.Length = 262144;
_asyncCallback = OnReceive;
sSocketName is a state string object (sSocketName = "History")

AsynCallback委托方法:

private void OnReceive(IAsyncResult asyn)
{
    if (asyn.AsyncState.ToString().Equals("History"))
    {
       int receivedBytes = _socket.EndReceive(asyn);
       string data = Encoding.ASCII.GetString(_buffer, 0, receivedBytes);
       //...
    }
    //...
}

receivedBytes是一个整数,表示接收的字节数。在我的情况下,它大约是23,000 - > 25000

套接字服务器是一个互联网服务器,它在字符串消息方面不断将原始数据推送到我的客户端套接字,并且它有超过25,000字节的数据。

所以我的问题:

  1. 什么决定接收的字节数?
  2. 什么决定接收是否结束?

1 个答案:

答案 0 :(得分:2)

当"完成"时,不一定会触发异步回调。消息发送。它读取尽可能多的字节数。只有您可以确定是否已收到所有数据。因此,如果您正在发送字符串" Hello World",那么在一次回调中首次接收" Hell"是完全有效的方案," o世界"在下一个。

您必须通过滚动自己的协议来确定邮件的长度,例如通过在数据长度之前添加您要发送的邮件。发送。

作为一个简单示例,假设字符是一个字节,最大消息长度是255,并且您希望发送一个字节字符串。你需要做的是保持一个读者状态",这样你就可以跟踪你在阅读信息的位置,而不是假设它将是一切。这是一个非常粗糙的代码示例,但我希望你能得到我的漂移。

private enum State
{
   MessageLength
   MessageData
}

private State _state;
private void OnEndReceive(IAsyncCallback ia)
{
    int bytesRead = _socket.EndReceive(ia);


    if (_state == MessageLength) 
    {
        // read and store the message length byte
    }
    else if (_state == State.MessageData)
    {
        // read message data up to the number of bytes received .
        // if there's data left to be read for the current message, read it.
        // if more bytes have been received than there is message data, it means there's a 
        // new message already waiting
    }

}