由于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端口并监听客户端,是不是很简单呢?

posted on 2010-10-02 10:53  zeroengine  阅读(535)  评论(1编辑  收藏  举报