gpt4 book ai didi

C# SocketAsyncEventArgs 处理接收和发送数据

转载 作者:可可西里 更新时间:2023-11-01 02:30:49 30 4
gpt4 key购买 nike

我试图理解 C# 中的“SocketAsyncEventArgs”类。 http://msdn.microsoft.com/en-us/library/system.net.sockets.socketasynceventargs.aspx

我正在学习本教程: http://www.codeproject.com/Articles/83102/C-SocketAsyncEventArgs-High-Performance-Socket-Cod

现在我陷入了我应该如何使用我的服务器处理数据的问题。我想要做的是为连接的客户端使用 SocketAsyncEventArgs,在 BufferManager 中分配了 512 字节的缓冲区空间。然后我想做的是将 byte[] 数据解码到我自己的自定义类 (ClientPacket) 中,该类包含用于解码和读取的 byte[]。

这一切都很好,但我的服务器并不总是响应数据问题是:

我是否使用 1 个 SocketAsyncEventArgs 进行接收并循环处理接收数据,然后在需要发送时从池中分配一个 SocketAsyncEventArgs,然后在完成时返回它?

SocketAsyncEventArgs 如何知道读取何时完成? (当它在用新数据覆盖它之前完成 byte[] 缓冲区时)就像如果我不响应它完成后如何返回到池中?

最佳答案

我只使用一个 SocketAsyncEventArgs 实例来满足我的所有需求。我只是在每个请求之间重置缓冲区(通过将其设置为新的 Byte[])。

一旦我连接并引用了 Socket,我就开始像这样监听:

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

socket.ReceiveAsync(e);
}

我有一个重置缓冲区的辅助函数:

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

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

我像这样处理数据:

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

ResetBuffer(e);

socket.ReceiveAsync(e);
}

在ProcessData中,您可以根据需要使用字节数组来拉取数据。我用它来创建一个 MemoryStream,然后将其反序列化到我的类中(类似于 ClientPacket),如下所示:

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
}
}

关于你的最后一个问题。该框架处理与底层 TCP 协议(protocol)等相关的所有事情,因此您可以依赖在有数据要处理时调用的事件处理程序。使用 e.BytesTransferred 值来指示您实际收到的数据量,它可能小于但永远不会超过您的缓冲区大小(我的代码中的 SocketBufferSize)。如果消息大于缓冲区大小,TCP 基础结构将缓冲消息并根据 SocketBufferSize 将它们以 block 的形式发送给您(通过为每个 block 引发一次事件)。如果这是一个问题,只需增加 SocketBufferSize 直到您的大部分消息在一个 block 中被接收。

分 block 的缺点是消息可能会被基础设施合并,这意味着您可能需要一种方法来判断第一条消息何时结束。典型的方法包括在您的消息前加上一个指示消息长度的 4 字节整数。如果需要,我可以详细说明。

希望对您有所帮助。

关于C# SocketAsyncEventArgs 处理接收和发送数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9018507/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com