Files
1440WGJ/SimpleServer/Server.cs
T
2026-07-14 13:55:17 +08:00

273 lines
8.3 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 SimpleCommunication;
using System.Windows.Forms;
namespace SimpleCommunication
{
public class Server : IDisposable
{
#region DataMember
public TcpListener listener;
public Client currentClient;
private object listenerLock = new object();//锁TcpListener;在BeginAcceptClient,EndAcceptClient,ServerClose这3函数使用;ServerClose之后不能再调用BeginAcceptClient,EndAcceptClient
/// <summary>
/// 服务器是否启用监听
/// </summary>
public 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<string> RecvMsgEvent;
public event DlgNoParam LocalDisconnectEvent;
public event DlgOneParam<string> RemoteDisconnectEvent;
public bool IsConnected => (listener != null && serverStart) ? true : false;
#endregion
#region 服务器监听启动关闭和连接接收
public bool Start(ComboBox Server_IP, TextBox txtPort, int maxClient = 10)
{
bool result = false;
try
{
if (!string.IsNullOrEmpty(Server_IP.Text) && !string.IsNullOrEmpty(txtPort.Text))
{
if (Convert.ToInt32(txtPort.Text) > 1024)
{
IPAddress ipAddr = IPAddress.Parse(Server_IP.Text);
IPEndPoint point = new IPEndPoint(ipAddr, Convert.ToInt32(txtPort.Text));
listener = new TcpListener(point);
listener.Start();
result = true;
serverStart = true;
if (ServerStartEvent != null)
{
ServerStartEvent();
}
}
}
}
catch(Exception ex)
{
throw ex;
}
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
{
}
}
/// <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
{
}
}
/// <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
{
}
return result;
}
#endregion
#region Client相关操作
private void InitClient(TcpClient tcpclient)
{
currentClient = new Client(tcpclient);
ClientDlgSubscribe(true);
currentClient.BeginRead();//即使在这之前服务器断开,该函数返回值也等于1
}
/// <summary>
/// InitClient,CurrentClient_LocalDisconnectEvent,Client_DisconnectEvent调用到
/// 在事务处理结束后调用到
/// </summary>
/// <param name="add"></param>
public void ClientDlgSubscribe(bool add)
{
if (add)
{
currentClient.NewClientEvent += new DlgOneParam<string>(Client_NewClientEvent);
currentClient.RecvMsgEvent += new DlgOneParam<string>(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<string>(Client_RecvMsgEvent);
currentClient.RemoteDisconnectEvent -= new DlgOneParam<string>(Client_DisconnectEvent);
currentClient.LocalDisconnectEvent -= new DlgNoParam(CurrentClient_LocalDisconnectEvent);
}
}
public bool SendMsg(string msg)
{
bool result = false;
try
{
if (currentClient.SendMsg(msg))
{
result = true;
}
}
catch
{
}
return result;
}
/// <summary>
/// 客户端连接情况下断开连接时调用,释放资源时调用
/// </summary>
/// <returns></returns>
public bool DisconnectClient()
{
bool result = false;
try
{
if (currentClient != null)
{
currentClient.Dispose();
result = true;
}
}
catch
{
}
return result;
}
public void Client_NewClientEvent(string param)
{
if (NewClientEvent != null)
{
NewClientEvent(param);
}
}
public void Client_RecvMsgEvent(string 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
}
}