using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace GeneralGommunication
{
    public class GComm_TcpListen
    {
        /// <summary>
        /// IP 地址 and 端口号
        /// </summary>
        public string Addr { get; set; }

        IPEndPoint LocalEp => Misc.StringConverter.ToIPEndPoint(Addr);

        /// <summary>
        /// 运行中
        /// </summary>
        public bool IsRunning { get; private set; }

        public event Action<Socket> NewConnection;

        Socket fd_listen;
        CancellationTokenSource cts;

        public GComm_TcpListen() 
        {
            
        }

        /// <summary>
        /// 开始
        /// </summary>
        public void Start()
        {
            if (IsRunning)
                return;

            cts = new CancellationTokenSource();
            Task.Factory.StartNew(() =>
            {
                IsRunning = true;
                fd_listen = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                fd_listen.Bind(LocalEp);
                fd_listen.Listen(5);
                //1秒内，需要收到信息
                fd_listen.ReceiveTimeout = 1000;
                //1秒内，必须发送完
                fd_listen.SendTimeout = 1000;
                fd_listen.Blocking = true;

                while (true)
                {
                    if (cts.IsCancellationRequested)
                    {
                        //关闭全部连接
                        break;
                    }

                    Socket connsd;
                    try
                    {
                        connsd = fd_listen.Accept();
                    }
                    catch (Exception e)
                    {
                        //肯定被强制退出
                        break;
                    }

                    NewConnection(connsd);
                }

                fd_listen.Close();
                IsRunning = false;
            });
        }

        /// <summary>
        /// 接收
        /// </summary>
        public void Stop()
        {
            if (!IsRunning)
                return;
            fd_listen.Close();
            cts.Cancel();
        }


    }
}
