异步TCP服务器/客户端方式

本文关键字:客户端 方式 服务器 TCP 异步 | 更新日期: 2023-09-27 18:17:46

我目前正在开发一个异步TCP客户端/服务器项目。多个客户端将连接到服务器(~100),并且我正在发送大小为0.7mb的对象。我想发送数据(binaryformatter序列化)并行到所有客户端。因此我写了下面的代码:

TCP服务器:

    private Task _pending = Task.FromResult<bool>(true);
    /// <summary>
    /// Objekt senden
    /// </summary>
    public async void Send(object data)
    {
        var previousTask = _pending;
        _pending = Task.Run(async () =>
        {
            await previousTask;
            MemoryStream ms = new MemoryStream();
            _serializer.Serialize(ms, data, Settings.Serialisation);
            if (Settings.UseCompression)
                ms = new MemoryStream(_compression.Compress(ms));
            if (Settings.Stream.AppendSignature)
                new MemoryStream(Settings.Stream.Signature).CopyTo(ms);
            Send(ms.ToArray());
            ms.Dispose();
        });
        await _pending;
    }
    public void Send(byte[] data)
    {
        try
        {
            lock (_lock)
            {
                _clients.ForEach(c => c.Send(data));
            }
        }catch(System.Exception ex)
        {
            ExceptionHandler.HandleException(ex, "Error while sending data", this);
        }
    }

这是我的客户端处理程序发送方法

public void Send(byte[] data)
    {
        if (State != ConnectionState.Connected)
            return;
        try
        {
            _tcpsocket.SendAsync(CreateSendEventArgs(data));
        }
        catch (System.Exception ex)
        {
            ExceptionHandler.HandleException(ex, "Error on Send", this, LogLevel.Debug);
            Disconnect();
        }
    }

由于某些原因,发送方法不是真正并行的,客户端在随机时间接收数据。我猜我是做错了这个async/await的东西。

KR Manuel

异步TCP服务器/客户端方式

你在等待每一个发送,为什么不全部等待呢?

一些PSEUDO可能会有帮助。

public async Task Send(object data)
{
    var newTask = Task.Run(async () =>
    {
        MemoryStream ms = new MemoryStream();
        _serializer.Serialize(ms, data, Settings.Serialisation);
        if (Settings.UseCompression)
            ms = new MemoryStream(_compression.Compress(ms));
        if (Settings.Stream.AppendSignature)
            new MemoryStream(Settings.Stream.Signature).CopyTo(ms);
        Send(ms.ToArray());
        ms.Dispose();
    });
    return newTask;
}
public void Send(byte[] data)
{
    try
    {
        lock (_lock)
        {
            Task[] tasks = _clients.Select(c => c.Send(data)).ToArray();
            await Task.WhenAll(tasks);
        }
    }catch(System.Exception ex)
    {
        ExceptionHandler.HandleException(ex, "Error while sending data", this);
    }
}
相关文章: