zoukankan      html  css  js  c++  java
  • C# Socket系列一 简单的创建socket的监听

    socket的应用场景,在快速,稳定,保持长连接的数据传输代码。Http也是socket封装出来的,基于一次请求一次回复,然后断开的socket连接封装。

    比如我们常见的游戏服务器,目前的很火的物联网服务器,都需要开启socket服务器去监听实时传输的数据。

    那么我们如何实现socket的监听呢。说到这里,我们需要知道,socket的监听分为tcp和udp两种形式,但是tcp其实是udp封装而来的,可看做可靠的udp传输,基于udp的定向传输,收到消息回复发送方收到消息。等验证,来实现tcp的数据传输,所以一般我们tcp的传输相对udp稍微慢一点。

    我们先将一下socket 的tcp状态创建一个TCPListener类

    /// <summary>
        /// 建立TCP通信监听服务
        /// </summary>
        internal class TCPListener
        {
            private IPEndPoint _IP;
            private Socket _Listeners;
            private volatile bool IsInit = false;
            private List<TSocketBase> sockets = new List<TSocketBase>();
    
            /// <summary>
            /// 初始化服务器
            /// </summary>
            public TCPListener(string ip = "0.0.0.0", int port = 9527)
            {
                IsInit = true;
                IPEndPoint localEP = new IPEndPoint(IPAddress.Parse(ip), port);
                this._IP = localEP;
                try
                {
                    Console.WriteLine(string.Format("Listen Tcp -> {0}:{1} ", ip, port));
                    this._Listeners = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                    this._Listeners.Bind(this._IP);
                    this._Listeners.Listen(5000);
                    SocketAsyncEventArgs sea = new SocketAsyncEventArgs();
                    sea.Completed += new EventHandler<SocketAsyncEventArgs>(this.AcceptAsync_Async);
                    this.AcceptAsync(sea);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    this.Dispose();
                }
            }
    
            private void AcceptAsync(SocketAsyncEventArgs sae)
            {
                if (IsInit)
                {
                    if (!this._Listeners.AcceptAsync(sae))
                    {
                        AcceptAsync_Async(this, sae);
                    }
                }
                else
                {
                    if (sae != null)
                    {
                        sae.Dispose();
                    }
                }
            }
    
            private void AcceptAsync_Async(object sender, SocketAsyncEventArgs sae)
            {
                if (sae.SocketError == SocketError.Success)
                {
                    var socket = new TSocketClient(sae.AcceptSocket);
                    sockets.Add(socket);
                    Console.WriteLine("Remote Socket LocalEndPoint:" + sae.AcceptSocket.LocalEndPoint + " RemoteEndPoint:" +
                                      sae.AcceptSocket.RemoteEndPoint.ToString());
                }
                sae.AcceptSocket = null;
                if (IsInit)
                {
                    this._Listeners.AcceptAsync(sae);
                }
                else
                {
                    sae.Dispose();
                }
            }
    
            /// <summary>
            /// 释放资源
            /// </summary>
            public void Dispose()
            {
                if (IsInit)
                {
                    IsInit = false;
                    this.Dispose(true);
                    GC.SuppressFinalize(this);
                }
            }
    
            /// <summary>
            /// 释放所占用的资源
            /// </summary>
            /// <param name="flag1"></param>
            protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1)
            {
                if (flag1)
                {
                    if (_Listeners != null)
                    {
                        try
                        {
                            Console.WriteLine(string.Format("Stop Listener Tcp -> {0}:{1} ", this.IP.Address.ToString(),
                                this.IP.Port));
                            _Listeners.Close();
                            _Listeners.Dispose();
                        }
                        catch
                        {
                        }
                    }
                }
            }
    
            /// <summary>
            /// 获取绑定终结点
            /// </summary>
            public IPEndPoint IP
            {
                get { return this._IP; }
            }
        }
    

      

    主要两点我们socket的初始化代码 new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);初始化的类型是基于tcp。

    还有就是我们绑定ip地址,过去很多人socket的bind地址习惯写成127.0.0.1(测试环境)或者读取网卡信息,读取ip地址,这样麻烦,代码要写很多,切不符合多网卡多线路实际环境。我们用0.0.0.0是表示开启ipv4的所有线路监听,包括你的多路网卡,以及127.0.0.1

    复制代码
    1     class Program
    2     {
    3         static void Main(string[] args)
    4         {
    5             TCPListener tcp = new TCPListener();
    6             Console.ReadLine();
    7         }
    8     }
    复制代码

    我们运行看一下效果

    接下来我们使用telnet测试一下

    开启telnet

    然后打开cmd 

    输入 telnet 127.0.0.1 9527

    我们看到收到了一个连接

  • 相关阅读:
    Server Tomcat v8.0 Server at localhost was unable to start within 45 seconds. If the server requires more time, try increasing the timeout in the server editor.
    用户画像——“打标签”
    python replace函数替换无效问题
    python向mysql插入数据一直报TypeError: must be real number,not str
    《亿级用户下的新浪微博平台架构》读后感
    【2-10】标准 2 维表问题
    【2-8】集合划分问题(给定要分成几个集合)
    【2-7】集合划分问题
    【2-6】排列的字典序问题
    【2-5】有重复元素的排列问题
  • 原文地址:https://www.cnblogs.com/soundcode/p/7238610.html
Copyright © 2011-2022 走看看