92 lines
2.8 KiB
C#
92 lines
2.8 KiB
C#
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<SocketClient> _clients = new List<SocketClient>();
|
|
private readonly TcpListener _listener;
|
|
private readonly List<Socket> _readableSockets = new List<Socket>();
|
|
private readonly List<Socket> _writableSockets = new List<Socket>();
|
|
private readonly Dictionary<Socket, SocketClient> _socketMap = new Dictionary<Socket, SocketClient>();
|
|
private int _port;
|
|
|
|
public SocketServer(int port)
|
|
{
|
|
_port = port;
|
|
|
|
_listener = new TcpListener(IPAddress.Any, port);
|
|
_listener.Start();
|
|
}
|
|
|
|
public IList<SocketClient> 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)
|
|
{
|
|
// New connection
|
|
Logger.WriteInternal("[HI!] 新的客户端接入!");
|
|
|
|
var c = new SocketClient(this, _listener.AcceptTcpClient());
|
|
|
|
_clients.Add(c);
|
|
_socketMap.Add(c.Socket.Client, c);
|
|
|
|
NewClient(c);
|
|
}
|
|
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)
|
|
{
|
|
Console.WriteLine("连接关闭");
|
|
|
|
_socketMap.Remove(client.Socket.Client);
|
|
_clients.Remove(client);
|
|
}
|
|
}
|
|
} |