大学IT网 - 最懂大学生的IT学习网站! QQ资料交流群:367606806
当前位置:大学IT网 > C#技巧 > 写自己的Socket框架(一)

写自己的Socket框架(一)(1)

关键词:Socket框架  阅读(3399) 赞(11)

[摘要]本文是对写自己的Socket框架(一)的讲解,对学习C#编程技术有所帮助,与大家分享。

本系列仅介绍可用于生产环境的C#异步Socket框架,如果您在其他地方看到类似的代码,不要惊讶,那可能就是我在参考开源代码时,直接“剽窃”过来的。

1、在脑海里思考一下整个socket的链接的处理流程,于是便有了下图。

2、首先就开始监听,代码如下:

public override bool Start()
        {
            this._socket = new System.Net.Sockets.Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            //设置KeeyAlive,如果客户端不主动发消息时,Tcp本身会发一个心跳包,来通知服务器,这是一个保持通讯的链接。
            //避免等到下一次通讯时,才知道链接已经断开。
            this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.KeepAlive, true);
            this._socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
            try
            {
                this._socket.Bind(base.SocketConfig.Point);
                this._socket.Listen(base.SocketConfig.Backlog);

                this._socket_args = new SocketAsyncEventArgs();
                this._socket_args.Completed += new EventHandler<SocketAsyncEventArgs>(AcceptSocketCompleted);

                //在链接过来的时候,如果IO没有挂起,则AcceptAsync为False,表明同步完成。
                if (!this._socket.AcceptAsync(this._socket_args))
                {
                    AcceptSocketCompleted(this._socket, this._socket_args);
                }
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }


void AcceptSocketCompleted(object sender, SocketAsyncEventArgs e)
        {
            System.Net.Sockets.Socket socket = null;
            if (e.SocketError != SocketError.Success)
            {
                    return;
            }
            else
            {
                socket = e.AcceptSocket;
            }
            e.AcceptSocket = null;
            bool willRaiseEvent = false;
            try
            {
                //继续监听该端口,在处理逻辑时,不影响其他链接的数据传送。
                willRaiseEvent = this._socket.AcceptAsync(e);
            }
            catch (Exception ex)
            {
                willRaiseEvent = true;
            }

            if (socket != null)
                OnNewClientAccepted(socket, null);

            if (!willRaiseEvent)
                AcceptSocketCompleted(null, e);
        }

3、这个时候链接过来了,就要开始入队列了,如果没有这方面的需求,这一步可以忽略,代码如下:

public class SocketProxy
    {
        public System.Net.Sockets.Socket Client;

        public DateTime Timeout = DateTime.Now;

    }


public class SocketConnectionQueue : IDisposable
    {
        private Queue<SocketProxy> _queue;

        private readonly object _syncObject = new object();

        private bool _isStop = false;

        private Thread _thread;

        public Action<SocketProxy> Connected;

        public SocketConnectionQueue()
        {
            if (_queue == null)
            {
                _queue = new Queue<SocketProxy>();
            }

            if (_thread == null)
            {
                _thread = new Thread(Thread_Work)
                {
                    IsBackground = true,
                    Priority = ThreadPriority.Highest

                };
                _thread.Start();
            }
        }

        public void Push(SocketProxy connect)
        {
            lock (_syncObject)
            {
                if (_queue != null)
                {
                    _queue.Enqueue(connect);
                }
            }
        }

        public void Thread_Work()
        {
            while (!_isStop)
            {
                SocketProxy[] socketConnect = null;
                lock (_syncObject)
                {
                    if (_queue.Count > 0)
                    {
                        socketConnect = new SocketProxy[_queue.Count];
                        _queue.CopyTo(socketConnect, 0);
                        _queue.Clear();
                    }
                }

                if (socketConnect != null && socketConnect.Length > 0)
                {
                    foreach (var client in socketConnect)
                    {
                        if (Connected != null)
                        {
                            Connected.Invoke(client);
                        }
                    }
                }
                Thread.Sleep(10);
            }
        }

        public void Dispose()
        {
            _isStop = true;
            if (_thread != null)
            {
                _thread.Join();
            }
        }
    }
«上一页12下一页»


相关评论