20200126_BDDM_upperpc/SimpleServer/Server_10.cs

266 lines
7.9 KiB
C#
Raw Normal View History

2023-07-27 02:53:17 +00:00
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Threading;
using System.Net;
using SimpleServer;
namespace SimpleServer
{
public class Server_10 : IDisposable
{
#region DataMember
private TcpListener listener;
private Client currentClient;
private object listenerLock = new object();//锁TcpListener在BeginAcceptClientEndAcceptClientServerClose这3函数使用ServerClose之后不能再调用BeginAcceptClientEndAcceptClient
private bool serverStart = false;
private EventWaitHandle eventWaitHdl = new EventWaitHandle(false, EventResetMode.ManualReset);
//在事务处理结束后才触发下列事件
public event DlgNoParam ServerStartEvent;
public event DlgNoParam ServerCloseEvent;
public event DlgOneParam<string> NewClientEvent;
public event DlgOneParam<byte[]> RecvMsgEvent;
public event DlgNoParam LocalDisconnectEvent;
public event DlgOneParam<string> RemoteDisconnectEvent;
#endregion
#region
public bool Start(string ip, int port)
{
bool result = false;
try
{
if (!string.IsNullOrEmpty(ip) && port > 1024)
{
IPAddress ipAddr = IPAddress.Parse(ip);
IPEndPoint point = new IPEndPoint(ipAddr, port);
listener = new TcpListener(point);
listener.Start();
result = true;
serverStart = true;
if (ServerStartEvent != null)
{
ServerStartEvent();
}
}
}
catch
{
throw;
}
return result;
}
/// <summary>
/// 有互斥资源
/// 接收连接主入口,监听启动后调用和每次接收到连接后调用
/// </summary>
public void BeginAcceptClient()
{
try
{
while (true)
{
eventWaitHdl.Reset();
lock (listenerLock)
{
if (serverStart)
{
listener.BeginAcceptTcpClient(EndAcceptClient, null);
}
else
{
return;
}
}
eventWaitHdl.WaitOne();
}
}
catch
{
throw;
}
}
/// <summary>
/// 有互斥资源
/// 接收到客户端连接时调用到关闭listener时也调用到
/// </summary>
/// <param name="ar"></param>
private void EndAcceptClient(IAsyncResult ar)
{
try
{
TcpClient tcpclient = null;
lock (listenerLock)
{
if (serverStart)
{
tcpclient = listener.EndAcceptTcpClient(ar);//在这句话之前或者client.BeginRead之前断掉远程客户端都没事tcpclient都不为null
}
}
eventWaitHdl.Set();
if (tcpclient != null)//listener.stop后tcpclient == null,不会进入下面代码
{
InitClient(tcpclient);
}
}
catch
{
//throw;
}
}
/// <summary>
/// 有互斥资源
/// 在listener监听状态下关闭listener时调用资源释放时调用
/// </summary>
/// <returns></returns>
public bool ServerClose()
{
bool result = false;
try
{
lock (listenerLock)
{
if (serverStart)
{
serverStart = false;
listener.Stop();
result = true;
if (ServerCloseEvent != null)
{
ServerCloseEvent();
}
}
}
}
catch
{
throw;
}
return result;
}
#endregion
#region Client相关操作
private void InitClient(TcpClient tcpclient)
{
currentClient = new Client(tcpclient);
ClientDlgSubscribe(true);
currentClient.BeginRead();//即使在这之前服务器断开该函数返回值也等于1
}
/// <summary>
/// InitClientCurrentClient_LocalDisconnectEventClient_DisconnectEvent调用到
/// 在事务处理结束后调用到
/// </summary>
/// <param name="add"></param>
public void ClientDlgSubscribe(bool add)
{
if (add)
{
currentClient.NewClientEvent += new DlgOneParam<string>(Client_NewClientEvent);
currentClient.RecvMsgEvent += new DlgOneParam<byte[]>(Client_RecvMsgEvent);
currentClient.RemoteDisconnectEvent += new DlgOneParam<string>(Client_DisconnectEvent);
currentClient.LocalDisconnectEvent += new DlgNoParam(CurrentClient_LocalDisconnectEvent);
}
else
{
currentClient.NewClientEvent -= new DlgOneParam<string>(Client_NewClientEvent);
currentClient.RecvMsgEvent -= new DlgOneParam<byte[]>(Client_RecvMsgEvent);
currentClient.RemoteDisconnectEvent -= new DlgOneParam<string>(Client_DisconnectEvent);
currentClient.LocalDisconnectEvent -= new DlgNoParam(CurrentClient_LocalDisconnectEvent);
}
}
public bool SendMsg(byte[] msg)
{
bool result = false;
try
{
if (currentClient.SendMsg(msg))
{
result = true;
}
}
catch
{
throw;
}
return result;
}
/// <summary>
/// 客户端连接情况下断开连接时调用,释放资源时调用
/// </summary>
/// <returns></returns>
public bool DisconnectClient()
{
bool result = false;
try
{
if (currentClient != null)
{
currentClient.Dispose();
result = true;
}
}
catch
{
throw;
}
return result;
}
public void Client_NewClientEvent(string param)
{
if (NewClientEvent != null)
{
NewClientEvent(param);
}
}
public void Client_RecvMsgEvent(byte[] param)
{
if (RecvMsgEvent != null)
{
RecvMsgEvent(param);
}
}
public void Client_DisconnectEvent(string param)
{
ClientDlgSubscribe(false);
if (RemoteDisconnectEvent != null)
{
RemoteDisconnectEvent(param);
}
}
public void CurrentClient_LocalDisconnectEvent()
{
ClientDlgSubscribe(false);
if (LocalDisconnectEvent != null)
{
LocalDisconnectEvent();
}
}
#endregion
#region
public void Dispose()
{
ServerClose();
DisconnectClient();
}
#endregion
}
}