2024-09-10 00:31:40 +08:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
|
2024-09-10 01:13:20 +08:00
|
|
|
|
namespace PSO2SERVER.Network
|
2024-09-10 00:31:40 +08:00
|
|
|
|
{
|
|
|
|
|
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)
|
|
|
|
|
{
|
|
|
|
|
var c = new SocketClient(this, _listener.AcceptTcpClient());
|
|
|
|
|
|
2024-12-21 03:15:29 +08:00
|
|
|
|
Logger.WriteInternal("[HI!] 新的客户端接入!");
|
|
|
|
|
|
2024-09-10 00:31:40 +08:00
|
|
|
|
_clients.Add(c);
|
|
|
|
|
_socketMap.Add(c.Socket.Client, c);
|
|
|
|
|
|
|
|
|
|
NewClient(c);
|
2024-12-02 11:27:14 +08:00
|
|
|
|
// 获取接入客户端的 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!] 新的客户端接入!");
|
|
|
|
|
}
|
2024-09-10 00:31:40 +08:00
|
|
|
|
}
|
|
|
|
|
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)
|
|
|
|
|
{
|
2024-09-11 19:17:42 +08:00
|
|
|
|
Logger.Write("断开客户端连接.");
|
2024-09-10 00:31:40 +08:00
|
|
|
|
|
|
|
|
|
_socketMap.Remove(client.Socket.Client);
|
|
|
|
|
_clients.Remove(client);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|