C# SocketAsyncEventArgs handling receive and send data

本小妞迷上赌 提交于 2019-11-30 13:23:25

I only use one SocketAsyncEventArgs instance for all of my needs. I simply reset the buffer between each request (by setting it to a new Byte[]).

Once I have connected and have a reference to the Socket, I start listening like this:

public void StartListening(SocketAsyncEventArgs e)
{
    ResetBuffer(e);
    e.Completed += SocketReceive;

    socket.ReceiveAsync(e);
}

I have a helper function that resets the buffer:

private void ResetBuffer(SocketAsyncEventArgs e)
{
    var buffer = new Byte[SocketBufferSize];

    e.SetBuffer(buffer, 0, SocketBufferSize);
}

I process the data like:

private void SocketReceive(Object sender, SocketAsyncEventArgs e)
{
    ProcessData(e.Buffer, 0, e.BytesTransferred);

    ResetBuffer(e);

    socket.ReceiveAsync(e);
}

In ProcessData, you can use the byte array as needed to pull in the data. I use it to create a MemoryStream which I then deserialize into my class (similar to ClientPacket), as follows:

private void ProcessData(Byte[] data, Int32 count)
{
    using (var stream = new MemoryStream(data, 0, count))
    {
        var serializer = new XmlSerializer(typeof(ClientPacket));

        var packet = serializer.Deserialize(stream);

        // Do something with the packet
    }
}

As for your last question. The framework handles everything to do with the underlying TCP protocol, etc. so you can rely on the event handler being called whenever there is data to be processed. Use the e.BytesTransferred value to indicate the amount of data you actually received which may be smaller than but will never exceed your buffer size (SocketBufferSize in my code). If the message was larger than the buffer size, the TCP infrastructure will buffer the messages and send them to you in chunks based on SocketBufferSize (by raising the event once for each chunk). If this is a concern, simply increase SocketBufferSize until the majority of your message are received in one chunk.

The downside of the chunking is that messages may be merged by the infrastructure which means that you may need a way to tell when the first message has ended. Typical approaches include prefacing your message with a 4 byte integer that indicates the message length. I can elaborate more if needed.

Hope that helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!