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

时间:2016-11-12 10:23:24

标签: c# sockets asynchronous tcp

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

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

1 个答案:

答案 0 :(得分: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);
    }
}