20200126_BDDM_upperpc/SimpleServer/Server_10.cs
2023-07-27 10:53:17 +08:00

266 lines
7.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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
}
}