【问题标题】:Async TCP Server / Client Approach异步 TCP 服务器/客户端方法
【发布时间】:2016-11-12 10:23:24
【问题描述】:

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

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 的东西做错了。

韩国曼努埃尔

【问题讨论】:

  • 您需要向所有连接的客户端发送相同的数据,或者您可以单独处理每个客户端?
  • 通常我向所有客户端发送相同的数据,但有时我需要向特定客户端发送数据

标签: c# sockets asynchronous tcp


【解决方案1】:

您正在等待每次发送,为什么不等待所有发送?

一些 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);
    }
}

【讨论】:

  • 在您的发送方法中调用 c.send(data) 没有返回任务,正如您在上面的代码中看到的(客户端处理程序发送方法)。 socket.SendAsync 出于什么原因没有返回任务?
猜你喜欢
  • 1970-01-01
  • 2013-03-25
  • 1970-01-01
  • 2014-08-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-22
  • 2012-08-07
相关资源
最近更新 更多