zoukankan      html  css  js  c++  java
  • LoginGate

    由于CShape提供很好Socket封装的类,所以写起来也很方便~~~

    监听TcpListener ServerSocket;
    与LoginSvr之间的通讯TcpClient ClientSocket;

    其实,很多朋友在这里,都会觉得在这一方面很困惑,觉得没有像Delphi有控件。其实,CShape更简单。

    public void StartServer()
    {
        // 创建一个监听本地7000端口的ServerSocket对象
        ServerSocket = new TcpListener(5500);
        // 开始监听本地7000端口
       ServerSocket.Start();
    }

    以上代码,就实现了对本地7000端口的的监听,是不是很简单呢?下面来讲如何监听有客户端访问。

    public void StartServer()
    {
        // 创建一个监听本地7000端口的ServerSocket对象
        ServerSocket = new TcpListener(5500);
        // 开始监听本地7000端口
        ServerSocket.Start();
        // 异步监听客户端访问,其实这里相当于新启动了一个进程。
        ServerSocket.BeginAcceptTcpClient(new AsyncCallback(ComplageAcceptTcpClient), null);
    }

    private void ComplageAcceptTcpClient(IAsyncResult ar)
    {
        // 监听是否有客户端传入,相当于Console.Read()一样。接收到有传入,就把传入的信息赋予Client。
        TcpClient Client = ServerSocket.EndAcceptTcpClient(ar);
    }

    这面就实现了对客户的监听,是不是很简单呢?下面来谈谈收到用户信息后如果处理。在DELPHI里,用了一个Timer对UserSession进行遍历然后发送。这里,其实也可以,不过既然有这么好的封装,何不创建一个Session的对象呢?
    public class TUserSession
    {
        // 远端信息
        public TcpClient Client { get; set; }
        // 是否连接
        public bool IsConnected { get; set; }
        // 开始连接的时间
        public int ConnectTick { get; set;}

        // 缓冲区大小,也就是接收信息的最大字节数
        private const int BufferSize = 4096;
        // 缓冲区
        private byte[] _buffer = new byte[BufferSize];

        // Socket发送与接收的一个流
        private NetworkStream _streamToClient;

        // 开始监听客户端传来的信息
        public void BeginRead()
        {
            if(Client != null)
            {
                // 获取Client的流(简化了很多代码)
            _streamToClient = Client.GetStream();
                // 看到了吧,这里又用到异步了,启动监听。
                _streamToClient.BeginRead(_buffer, BufferSize, new AsyncCallback(ComplateRead), null);
            }
        }

        private void ComplateRead(IAsyncResult ar)
        {
            int bytesRead;
            try
            {
                // 程序到这里会阻断,直到客户端发送数据。
                bytesRead = _streamToClient.EndRead(ar);
                if(bytesRead > 0)
                {
                    // 将接收到的信息转为字符
                    string RecviceText = Encoding.Default.GetString(_buffer, 0, bytesRead);

                    对这条接收到的信息怎么处理,就可以在这里实现了。

               // 继续监听客户端,只要客户端没有断开或服务断开客户端的连接,这里就成了无限的循环了
               // 因为bytesRead = _streamToClient.EndRead(ar);是阻断模式,所以不用担心会出现程序崩溃。
               _streamToClient.BeginRead(_buffer, BufferSize, new AsyncCallback(ComplateRead), null);
                }
                else
                {
                    // 如果客户端关闭或断开连接,就会发送一个0字节的流,所以这里要断开连接
                    if(_streamToClient != null)
                        _streamToClient.Dispose();
                    if(Client != null)
                        Client.Close();
                    this.IsConnected = false;
                }
            }
            catch(SocketExcept ex)
            {
            }
        }

        // 向客户端发送一条消息
        public void SendText(string text)
        {
            if(this.IsConnected)
            {
                byte[] sendBuffer = Encoding.Default.GetBytes(text);
                _streamToClient.Send(sendBuffer, 0, sendBuffer.Length);
            }
        }
    }

    public List<TUserSession> UserSession = new List<TUserSession>();

    这样,就OK了。是不是很简单?

    private void ComplageAcceptTcpClient(IAsyncResult ar)
    {
        // 监听是否有客户端传入,相当于Console.Read()一样。接收到有传入,就把传入的信息赋予Client。
        TcpClient Client = ServerSocket.EndAcceptTcpClient(ar);

        在这里可以加入一些过滤,比如连接IP数据是不是太多?是不是永久过滤的吖?如果是,直接Client.Close()掉就可以啦。

        // 当接到到一个客户端,就new一个Session对象
        TUserSession userSession = new TUserSession();
        userSession.Client = Client;
        userSession.IsConnected = true;
        userSession.ConnectTick = Environment.TickCount;
        userSession.BeginRead();
        UserSession.Add(userSession);

        // 最后别忘了加这一条,叫他无限循环。由于是阻断模式,所以到TcpClient Client = ServerSocket.EndAcceptTcpClient(ar);这里会停下,直到有新的客户端进来。
        ServerSocket.BeginAcceptTcpClient(new AsyncCallback(ComplageAcceptTcpClient), null);
    }

    这样,就完成了打开7000端口并监听客户端,是不是很简单呢?

  • 相关阅读:
    js 使用${}解析变量代替++
    laravel 返回自定义错误
    Java集合之HashMap源码解析
    Java集合之ArrayList源码解析
    Java集合之LinkedList源码解析
    保证消息可靠性传输以及幂等性
    Java分布式系统---消息中间件
    Java中的日期与时间
    Java时区问题
    数据测试002:利用Jmeter推送测试数据(上)
  • 原文地址:https://www.cnblogs.com/zerovirs/p/1841194.html
Copyright © 2011-2022 走看看