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

    我们看到收到了一个连接

  • 相关阅读:
    DataAnnotations
    使用BizTalk实现RosettaNet B2B So Easy
    biztalk rosettanet 自定义 pip code
    Debatching(Splitting) XML Message in Orchestration using DefaultPipeline
    Modifying namespace in XML document programmatically
    IIS各个版本中你需要知道的那些事儿
    关于IHttpModule的相关知识总结
    开发设计的一些思想总结
    《ASP.NET SignalR系列》第五课 在MVC中使用SignalR
    《ASP.NET SignalR系列》第四课 SignalR自托管(不用IIS)
  • 原文地址:https://www.cnblogs.com/soundcode/p/7238610.html
Copyright © 2011-2022 走看看