using System; using System.Collections.Generic; using System.Net; using System.Net.Sockets; namespace PSO2SERVER.Network { public class SocketServer { public delegate void NewClientDelegate(SocketClient client); private readonly List _clients = new List(); private readonly TcpListener _listener; private readonly List _readableSockets = new List(); private readonly List _writableSockets = new List(); private readonly Dictionary _socketMap = new Dictionary(); private int _port; public SocketServer(int port) { _port = port; _listener = new TcpListener(IPAddress.Any, port); _listener.Start(); } public IList Clients { get { return _clients.AsReadOnly(); } } public event NewClientDelegate NewClient; public void Run() { try { // Compile a list of possibly-readable sockets _readableSockets.Clear(); _readableSockets.Add(_listener.Server); _writableSockets.Clear(); foreach (var client in _clients) { _readableSockets.Add(client.Socket.Client); if (client.NeedsToWrite) _writableSockets.Add(client.Socket.Client); } Socket.Select(_readableSockets, _writableSockets, null, 1000000); foreach (var socket in _readableSockets) { if (socket == _listener.Server) { var c = new SocketClient(this, _listener.AcceptTcpClient()); Logger.WriteInternal("[HI!] 新的客户端接入!"); _clients.Add(c); _socketMap.Add(c.Socket.Client, c); NewClient(c); // 获取接入客户端的 IP 和端口 var clientEndPoint = c.Socket.Client.RemoteEndPoint as IPEndPoint; if (clientEndPoint != null) { string clientIp = clientEndPoint.Address.ToString(); int clientPort = clientEndPoint.Port; // 输出客户端的 IP 和端口 Logger.WriteInternal($"[HI!] 新的客户端接入! IP: {clientIp}, 端口: {clientPort}"); } else { // New connection Logger.WriteInternal("[HI!] 新的客户端接入!"); } } else { // Readable data if (socket.Connected) _socketMap[socket].OnReadable(); } } foreach (var socket in _writableSockets) if (socket.Connected) _socketMap[socket].OnWritable(); } catch (Exception ex) { Logger.WriteException("A socket error occurred", ex); } } internal void NotifyConnectionClosed(SocketClient client) { Logger.Write("断开客户端连接."); _socketMap.Remove(client.Socket.Client); _clients.Remove(client); } } }