using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ChuPiao.Common.Communication
{
    /// <summary>
    /// 简易Socket客户端
    /// </summary>
    public class SocketClientOfNotify : ISocketClient
    {
        private Socket _socket = null;
        private string _host;
        private int _port;
        private int _receiveTimeout;
        private int _sendTimeout;

        /// <summary>
        /// 新建socket客户端
        /// </summary>
        /// <param name="host">IP</param>
        /// <param name="port">端口</param>
        /// <param name="receiveTimeout">接收超时</param>
        /// <param name="sendTimeout">发送超时</param>
        public SocketClientOfNotify(string host, int port, int receiveTimeout, int sendTimeout)
        {
            _host = host;
            _port = port;
            _receiveTimeout = receiveTimeout;
            _sendTimeout = sendTimeout;
        }

        private bool Connection(string host, int port)
        {
            DisConnection();
            try
            {
                _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                _socket.ReceiveTimeout = _receiveTimeout;
                _socket.SendTimeout = _sendTimeout;
                //_socket.NoDelay = true;
                IPAddress ipAddress;
                IPAddress.TryParse(host, out ipAddress);
                if (ipAddress == null)
                {
                    IPHostEntry ipHostEntry = Dns.GetHostEntry(host);
                    ipAddress = ipHostEntry.AddressList[0];
                }
                IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, port);
                _socket.Connect(ipEndPoint);
            }
            catch (Exception exception)
            {
                throw new Exception("连接:" + host + " IP失败：" + exception.Message);
            }
            return true;
        }
        private bool DisConnection()
        {
            try
            {
                if (_socket != null)
                {
                    if (_socket.Connected)
                    {
                        _socket.Shutdown(SocketShutdown.Both);
                    }
                    _socket.Close();
                }
                _socket = null;
            }
            catch (Exception exception)
            {
                return false;
            }
            return true;
        }
        private bool IsConnected
        {
            get
            {
                if (_socket != null)
                {
                    return _socket.Connected;
                }
                return false;
            }
        }

        #region Implementation of ISocketClient

        /// <summary>
        /// 提交请求
        /// </summary>
        /// <param name="requestMsg"></param>
        /// <returns></returns>
        public string CommitRequest(string requestMsg)
        {
            try
            {
                if (!IsConnected)
                {
                    if (!Connection(_host, _port))
                    {
                        return null;
                    }
                }

                string retdata = "";

                byte[] contentData = Encoding.UTF8.GetBytes(requestMsg);
                //因为BitConverter.GetBytes是按小端字节序转换成byte数组，而网络字节序是大端字节序，所以进行转换
                byte[] headerData = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(contentData.Length));
                byte[] data = new byte[headerData.Length + contentData.Length];
                headerData.CopyTo(data, 0);
                contentData.CopyTo(data, headerData.Length);
                _socket.Send(data);

                byte[] buffer = new byte[4];
                _socket.Receive(buffer, 0, 4, SocketFlags.None);
                //因为BitConverter.GetBytes是按小端字节序转换成byte数组，而网络字节序是大端字节序，所以进行转换
                int contentLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(buffer, 0));
                if (contentLength > 0)
                {
                    buffer = new byte[contentLength];
                    _socket.Receive(buffer, 0, contentLength, SocketFlags.None);
                    retdata = Encoding.UTF8.GetString(buffer);
                }
                return retdata;
            }
            catch (Exception exception)
            {
                //DisConnection();
                throw new Exception(exception.Message);
            }
            finally
            {
                DisConnection();
            }
        }

        /// <summary>
        /// 关闭客户端
        /// </summary>
        public void Close()
        {
            DisConnection();
        }

        #endregion
    }
}
