gpt4 book ai didi

c# AsyncSocket 服务器需要锁定?

转载 作者:太空宇宙 更新时间:2023-11-03 22:58:47 25 4
gpt4 key购买 nike

我写了一个 TCP 套接字服务器。一般来说,我希望有以下行为:

  • A Listening Socket can accept N Connections (There a multiple Listeners on different Ports (1337,733) )
  • 一个连接可以将自己认证为“客户端”,多个连接可以归为一个“客户端”
  • 多个连接可以同时接收/接收数据(并发)

这是我的服务器类:

class Server{    internal List ConnectionListeners;    internal bool IsListening = false;    internal Server()    {        this.ClientManager = new ClientManager();        this.ConnectionManager = new ConnectionManager();        this.ConnectionListeners = new List();    }    internal void AddConnectionListener(int Port)    {        ConnectionListener c = new ConnectionListener(Port);        c.AcceptedConnection += new ConnectionListener.AcceptedConnectionEventHandler(ConnectionProcessor.AcceptConnection);        ConnectionListeners.Add(c);    }    internal void RemoveConnectionListener(ConnectionListener ConnectionListener)    {        ConnectionListeners.Remove(ConnectionListener);    }    public delegate void OnStartListeningEventHandler();    public event OnStartListeningEventHandler OnStartListening;    internal void StartListening()    {        IsListening = true;        foreach (ConnectionListener cl in this.ConnectionListeners)        {            cl.StartListening();        }        OnStartListening?.Invoke();    }    public delegate void OnStopListeningEventHandler();    public event OnStopListeningEventHandler OnStopListening;    internal void StopListening()    {        ConnectionManager.DisconnectConnections();        foreach (ConnectionListener cl in this.ConnectionListeners)        {            cl.StopListening();        }        IsListening = false;        OnStopListening?.Invoke();    }}

ConnectionProcessor 的方法,其中我处理一个新的接受连接 (ConnectionProcessor.AcceptConnection):

        internal void AcceptConnection(Socket Socket)        {            Connection Connection = new Connection(Socket);            Connection.Sent += new Connection.SentEventHandler(onSend);            Connection.Received += new Connection.ReceivedEventHandler(onRecive);            Connection.Disconnected += new Connection.DisconnectedEventHandler(OnDisconnect);            Connection.Recive();            Logger.Instance.AddLog(new LogMessage(LogMessage.LogLevel.Normal, "Connection ("+Connection.ConnectionId+") Accepted"));            ConnectionManager.AddConnection(Connection);        }

连接管理器:

    class ConnectionManager    {        internal ConnectionManager()        {            this.Connections = new List();        }        internal void AddConnection(Connection Connection)        {            Connections.Add(Connection);            OnAddConnection(Connection);        }        internal void RemoveConnection(Connection Connection)        {            Connections.Remove(Connection);            OnRemoveConnection(Connection);        }        internal void DisconnectConnections()        {            foreach (Connection c in Connections)            {                c.Disconnect();            }        }    }

似乎一切正常,但我不确定并发性。

如您在 ConnectionManger 中所见,我将每个连接存储在一个列表 (Connections.Add(Connection)) 中。这样做够了吗?我必须关心一个普通的“列表”不是线程安全的吗?

我在 gerneal 中的“设计”是解决我的需求的正确方法吗?

最佳答案

由于您所做的只是在列表中添加\删除\枚举连接 - 您可以使用线程安全的集合,而无需任何锁。遗憾的是,没有 ConcurrentListConcurrentHashSet,但您可以将 ConcurrentDictionary 与虚拟键一起使用,可以直接使用,也可以通过包装在单独的类中:

class BasicConcurrentSet<T> : IEnumerable<T> {
private readonly ConcurrentDictionary<T, byte> _items = new ConcurrentDictionary<T, byte>();

public void Add(T item) {
_items.TryAdd(item, 0);
}

public void Remove(T item) {
byte tmp;
_items.TryRemove(item, out tmp);
}

IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}

public IEnumerator<T> GetEnumerator() {
foreach (var kv in _items) {
yield return kv.Key;
}
}
}

从此类并发集合中添加、删除和枚举项目是线程安全的。

class ConnectionManager {
private readonly BasicConcurrentSet<Connection> _connections = new BasicConcurrentSet<Connection>();

internal ConnectionManager() {

}

internal void AddConnection(Connection connection) {
_connections.Add(connection);
OnAddConnection(Connection);
}

internal void RemoveConnection(Connection connection) {
_connections.Remove(connection);
OnRemoveConnection(connection);
}

internal void DisconnectConnections() {
foreach (var connection in _connections) {
connection.Disconnect();
}
}
}

关于c# AsyncSocket 服务器需要锁定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44121059/

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