修正一下SocketManager中的SocketServer类

修正一下SocketManager中的SocketServer类

/**

 * 作者:王文斌

 * 做成日:2008-5-9

 * 版本:0.2

 * 说明:Socket服务端,接收到的信息放在队列里,开个线程,监听队列信息。

 *       目前客户端识别只提供ip识别,可以考虑利用SocketConn保存客户端识别名称

 * */

using System;

using System.Collections.Generic;

using System.Text;

using System.Net;

using System.Net.Sockets;

using System.Threading;

using System.IO;

using System.Collections;





namespace WWBClassLib.SocketManager

{

    /// <summary>

    /// 连接类

    /// </summary>

    public class SocketConn

    {

        /// <summary>

        /// 连接对象

        /// </summary>

        private Socket sock;



        /// <summary>

        /// 识别名称

        /// </summary>

        private string name;



        /// <summary>

        /// 连接对象

        /// </summary>

        public Socket Sock

        {

            set { sock = value; }

            get { return sock; }

        }



        /// <summary>

        /// 识别名称

        /// </summary>

        public string Name

        {

            set { name = value; }

            get { return name; }

        }



        /// <summary>

        /// 构造方法 服务端命名

        /// </summary>

        /// <param name="socket">连接</param>

        /// <param name="name">识别名</param>

        public SocketConn(Socket socket, string name)

        {

            sock = socket;

            this.name = name;

            

        }



        /// <summary>

        /// 构造方法,默认识别名为ip

        /// </summary>

        /// <param name="socket">连接对象</param>

        public SocketConn(Socket socket)

        {

            sock = socket;

            this.name = ((IPEndPoint)socket.RemoteEndPoint).Address.ToString();

        }

    }



    /// <summary>

    /// SocketConn专用集合类

    /// </summary>

    public class SocketConList

    {

        private List<SocketConn> list = new List<SocketConn>();



        public void ADD(SocketConn con)

        {

            list.Add(con);

        }

        public void Remove(SocketConn con)

        {

            list.Remove(con);

            

        }



        public void Remove(string name)

        {

            lock (list)

            {

                for (int i = 0; i < list.Count; i++)

                {

                    if (list[i].Name.Equals(name))

                    {

                        list.Remove(list[i]);

                    }

                }

                

            }

        }



        public void Remove(Socket sock)

        {

            lock (list)

            {

                for (int i = 0; i < list.Count; i++)

                {

                    if (list[i].Sock.Equals(sock))

                    {

                        list.Remove(list[i]);

                    }

                }

                

            }

        }



        public void Clear()

        {

            list.Clear();

            

        }



        public void RemoveAt(int i)

        {

            list.RemoveAt(i);

            

        }



        public SocketConn Find(string name)

        {

            lock (list)

            {

                for (int i = 0; i < list.Count; i++)

                {

                    if (list[i].Name.Equals(name))

                    {

                        return list[i];

                    }

                }

                

            }

            return null;

        }



        public List<SocketConn> List

        {

            get { return list; }

        }

        

    }



    /// <summary>

    /// 简单套接字服务端

    /// </summary>

    public class SocketServer2

    {

        /// <summary>

        /// 服务器IP

        /// </summary>

        private IPAddress serverIP;



        /// <summary>

        /// 完整终端地址包含端口

        /// </summary>

        private IPEndPoint serverFullAddr;



        /// <summary>

        /// 服务器端监听用Socket对象

        /// </summary>

        private Socket sock;



        /// <summary>

        /// 服务器监听线程

        /// </summary>

        private System.Timers.Timer myTimer;



        /// <summary>

        /// 保存链接用集合

        /// </summary>

        //private List<Socket> alSock;//当建立了多个连接时用于保存连接

        private SocketConList socklist;



        /// <summary>

        /// 端口号,默认15693

        /// </summary>

        private int portNo = 15693;



        /// <summary>

        /// 储存接受到的消息队列

        /// </summary>

        public Queue commands = new Queue();



        /// <summary>

        /// 构造函数 端口默认15693

        /// </summary>

        /// <param name="ServerIP">服务器ip</param>

        /// <param name="commands">消息队列</param>

        public SocketServer2(string ServerIP, Queue commands)

        {



            serverIP = IPAddress.Parse(ServerIP);

            this.commands = commands;

        }



        /// <summary>

        /// 构造函数,设定端口

        /// </summary>

        /// <param name="ServerIP">服务器ip</param>

        /// <param name="portNo">端口号</param>

        /// <param name="commands">消息队列</param>

        public SocketServer2(string ServerIP, int portNo, Queue commands)

        {

            serverIP = IPAddress.Parse(ServerIP);

            this.portNo = portNo;

            this.commands = commands;

        }



        /// <summary>

        /// 获取连接IP集合

        /// </summary>

        /// <returns>IP集合</returns>

        public List<string> GetListIPs()

        {

            List<string> list = new List<string>();

            lock (socklist)

            {

                for (int i = 0; i < socklist.List.Count; i++)

                {

                    list.Add(((IPEndPoint)socklist.List[i].Sock.RemoteEndPoint).Address.ToString());

                }

                

            }

            return list;

        }



        /// <summary>

        /// 启动监听,创建链接

        /// </summary>

        /// <returns>创建结果</returns>

        public bool StartLinsten()

        {

            //取得完整地址

            serverFullAddr = new IPEndPoint(serverIP, portNo);//取端口号



            try

            {



                //构造Socket对象,套接字类型为“流套接字”,指定五元组中的协议元



                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);



                //指定五元组中的本地二元,即本地主机地址和端口号



                sock.Bind(serverFullAddr);



                //监听是否有连接传入,指定挂起的连接队列的最大值为20



                sock.Listen(20);



            }

            catch

            {

                return false;

            }



            //初始化存储链接集合

            socklist = new SocketConList();







            //构造定时器,时间间隙为1秒,即每隔一秒执行一次accept()方法,以获取连接请求队列中//第一个挂起的连接请求



            myTimer = new System.Timers.Timer(1000);



            myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);



            myTimer.Enabled = true;

            return true;

        }



        /// <summary>

        /// 监听线程

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

        {

            //暂时中断线程

            myTimer.Enabled = false;



            //执行accept(),当挂起队列为空时将阻塞本线程,同时由于上一语句,定时器将停止,直//至有连接传入



            Socket acceptSock = sock.Accept();



            //将accept()产生的Socket对象存入ArrayList

            SocketConn conn = new SocketConn(acceptSock);

            socklist.ADD(conn);

            



            // 构造Threading.Timer对象,这将导致程序另启线程。线程将执行回调函数,该委托限制//函数参数须为object型。Threading.Timer构造器的第二个参数即传入回调函数的参数;第//三个参数指定调用回调函数之前的延时,取0则立即启动;最后一个参数指定调用回调函数//的时间间隔,取0则只执行一次。



            System.Threading.Timer ti = new System.Threading.Timer(new TimerCallback(ReceiveMsg), acceptSock, 0, 0);



            //重新启用线程

            myTimer.Enabled = true;



        }



        /// <summary>

        /// 接受信息方法

        /// </summary>

        /// <param name="obj"></param>

        private void ReceiveMsg(object obj)

        {

            //取得链接对象

            Socket acceptSock = (Socket)obj;



            try

            {



                while (true)

                {

                    //判断链接,未连接的移除

                    if (!acceptSock.Connected)

                    {

                        socklist.Remove(acceptSock);

                        acceptSock.Close();

                    }



                    //定义接收字节流

                    byte[] byteArray = new byte[1000];



                    byte[] comArray = new byte[1000];

                    //接受数据

                    acceptSock.Receive(byteArray);//接收数据



                    //判断数据有效性

                    if (!BitConverter.ToString(byteArray).Equals(BitConverter.ToString(comArray)))

                    {

                        //添加至消息队列

                        commands.Enqueue(byteArray);

                    }



                    

                }



            }



            catch (Exception ex)

            {

                //接收消息失败,关闭连接,移除链接

                acceptSock.Close();

                socklist.Remove(acceptSock);





            }



        }



        /// <summary>

        /// 发送消息

        /// </summary>

        /// <param name="message">消息字节流</param>

        /// <param name="ip">对象ip</param>

        /// <returns>结果</returns>

        public bool SendMessage(byte[] message, string ip)

        {

            //定义对象

            Socket sc = null;



            try

            {

                //多线程访问集合对象,遍历时需要锁定,避免便利同时数组变化错误

                SocketConn conn = socklist.Find(ip);

                sc = conn.Sock;



                //判断存在相应对象

                if (sc != null)

                {

                    //发送数据

                    sc.Send(message);

                    return true;

                }

                return false;



            }



            catch (Exception ex)

            {

                //发送错误,移除链接

                if (sc != null)

                {



                    sc.Close();

                    socklist.Remove(sc);



                }



                return false;



            }

        }

    }



    /// <summary>

    /// 简单套接字服务端

    /// </summary>

    public class SocketServer

    {

        /// <summary>

        /// 服务器IP

        /// </summary>

        private IPAddress serverIP; 



        /// <summary>

        /// 完整终端地址包含端口

        /// </summary>

        private IPEndPoint serverFullAddr;



        /// <summary>

        /// 服务器端监听用Socket对象

        /// </summary>

        private Socket sock;



        /// <summary>

        /// 服务器监听线程

        /// </summary>

        private System.Timers.Timer myTimer;



        /// <summary>

        /// 保存链接用集合

        /// </summary>

        private List<Socket> alSock;//当建立了多个连接时用于保存连接



        /// <summary>

        /// 端口号,默认15693

        /// </summary>

        private int portNo = 15693;



        /// <summary>

        /// 储存接受到的消息队列

        /// </summary>

        public Queue commands = new Queue();



        /// <summary>

        /// 构造函数 端口默认15693

        /// </summary>

        /// <param name="ServerIP">服务器ip</param>

        /// <param name="commands">消息队列</param>

        public SocketServer(string ServerIP,Queue commands)

        {

            

            serverIP = IPAddress.Parse(ServerIP);

            this.commands = commands;

        }



        /// <summary>

        /// 构造函数,设定端口

        /// </summary>

        /// <param name="ServerIP">服务器ip</param>

        /// <param name="portNo">端口号</param>

        /// <param name="commands">消息队列</param>

        public SocketServer(string ServerIP, int portNo, Queue commands)

        {

            serverIP = IPAddress.Parse(ServerIP);

            this.portNo = portNo;

            this.commands = commands;

        }



        /// <summary>

        /// 获取连接IP集合

        /// </summary>

        /// <returns>IP集合</returns>

        public List<string> GetListIPs()

        {

            List<string> list = new List<string>();

            lock (alSock)

            {

                for (int i = 0; i < alSock.Count; i++)

                {

                    list.Add(((IPEndPoint)alSock[i].RemoteEndPoint).Address.ToString());

                }

                

            }

            return list;

        }



        /// <summary>

        /// 启动监听,创建链接

        /// </summary>

        /// <returns>创建结果</returns>

        public bool StartLinsten()

        {

            //取得完整地址

            serverFullAddr = new IPEndPoint(serverIP, portNo);//取端口号

            

            try

            {



                //构造Socket对象,套接字类型为“流套接字”,指定五元组中的协议元



                sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);



                //指定五元组中的本地二元,即本地主机地址和端口号



                sock.Bind(serverFullAddr);



                //监听是否有连接传入,指定挂起的连接队列的最大值为20



                sock.Listen(20);



            }

            catch

            {

                return false;

            }



            //初始化存储链接集合

            alSock = new List<Socket>();







            //构造定时器,时间间隙为1秒,即每隔一秒执行一次accept()方法,以获取连接请求队列中//第一个挂起的连接请求



            myTimer = new System.Timers.Timer(1000);



            myTimer.Elapsed += new System.Timers.ElapsedEventHandler(myTimer_Elapsed);



            myTimer.Enabled = true;

            return true;

        }



        /// <summary>

        /// 监听线程

        /// </summary>

        /// <param name="sender"></param>

        /// <param name="e"></param>

        private void myTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)

        {

            //暂时中断线程

            myTimer.Enabled = false;



            //执行accept(),当挂起队列为空时将阻塞本线程,同时由于上一语句,定时器将停止,直//至有连接传入



            Socket acceptSock = sock.Accept();



            //将accept()产生的Socket对象存入ArrayList



            alSock.Add(acceptSock);



            // 构造Threading.Timer对象,这将导致程序另启线程。线程将执行回调函数,该委托限制//函数参数须为object型。Threading.Timer构造器的第二个参数即传入回调函数的参数;第//三个参数指定调用回调函数之前的延时,取0则立即启动;最后一个参数指定调用回调函数//的时间间隔,取0则只执行一次。



            System.Threading.Timer ti = new System.Threading.Timer(new TimerCallback(ReceiveMsg), acceptSock, 0, 0);



            //重新启用线程

            myTimer.Enabled = true;



        }



        /// <summary>

        /// 接受信息方法

        /// </summary>

        /// <param name="obj"></param>

        private void ReceiveMsg(object obj)

        {

            //取得链接对象

            Socket acceptSock = (Socket)obj;



            try

            {

                

                while (true)

                {

                    //判断链接,未连接的移除

                    if (!acceptSock.Connected)

                    {

                        alSock.Remove(acceptSock);

                        acceptSock.Close();

                    }



                    //定义接收字节流

                    byte[] byteArray = new byte[1000];



                    byte[] comArray = new byte[1000];

                    //接受数据

                    acceptSock.Receive(byteArray);//接收数据



                    //判断数据有效性

                    if (!BitConverter.ToString(byteArray).Equals(BitConverter.ToString(comArray)))

                    {

                        //添加至消息队列

                        commands.Enqueue(byteArray);

                    }



                    

                }



            }



            catch (Exception ex)

            {

                //接收消息失败,关闭连接,移除链接

                acceptSock.Close();

                alSock.Remove(acceptSock);

                



            }



        }



        /// <summary>

        /// 发送消息

        /// </summary>

        /// <param name="message">消息字节流</param>

        /// <param name="ip">对象ip</param>

        /// <returns>结果</returns>

        public bool SendMessage(byte[] message,string ip)

        {

            //定义对象

            Socket sc = null;



            try

            {

                //多线程访问集合对象,遍历时需要锁定,避免便利同时数组变化错误

                lock (alSock)

                {

                    //通过ip选择链接对象

                    for (int i = 0; i < alSock.Count; i++)

                    {

                        if (((IPEndPoint)alSock[i].RemoteEndPoint).Address.ToString().Equals(ip))

                        {

                            sc = alSock[i];

                            break;

                        }

                    }



                    

                    

                }

                //判断存在相应对象

                if (sc != null)

                {

                    //发送数据

                    sc.Send(message);

                    return true;

                }

                return false;



            }



            catch (Exception ex)

            {

                //发送错误,移除链接

                if (sc != null)

                {



                    sc.Close();

                    alSock.Remove(sc);



                }



                return false;



            }

        }

    }

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值