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

    我们看到收到了一个连接

  • 相关阅读:
    记录时间开销的好处
    jQuery实现轮播图效果
    读《论证是一门学问》
    sqrt.java
    关于perl:Fatal: failed to find source perl5db.pl for epic_breakpoints.pm解决方法
    JAVA基础——对象与引用概念(转载)
    对百度搜索看法的转变
    C输出格式——转载
    Java static关键字与静态块
    简单js实现弹出登陆框div层,背景变暗不可操作
  • 原文地址:https://www.cnblogs.com/soundcode/p/7238610.html
Copyright © 2011-2022 走看看