zoukankan      html  css  js  c++  java
  • [转]在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(二)

    一.TcpSvr的使用方法
      A.测试程序:
    using System;
      
    using Ibms.Net.TcpCSFramework;
      
    using System.Collections;
      
    using System.Net.Sockets;
      
    namespace Ibms.Test
      {
      
    /// <summary>
      
    /// 测试TcpSvr的类
      
    /// </summary>
      public class TestTcpSvr
      {
       
       
    public TestTcpSvr()
       {
       
       }
       
       
    public static void Main()
       {
       
    try
       {
       Console.WriteLine(
    "Begin to Test TcpSvr class");
       TestTcpSvr tts 
    = new TestTcpSvr();
       
    //TcpSvr svr = new TcpSvr(9050,4);//默认使用Encoding.Default编码方式
       TcpSvr svr = new TcpSvr(9050,4,new Coder(Coder.EncodingMothord.UTF8));
       svr.Resovlver 
    = new DatagramResolver("##");
       
    //定义服务器的4个事件
       
    //服务器满
       svr.ServerFull += new NetEvent(tts.ServerFull);
       
    //新客户端连接
       svr.ClientConn += new NetEvent(tts.ClientConn);
       
    //客户端关闭
       svr.ClientClose += new NetEvent(tts.ClientClose);
       
    //接收到数据
       svr.RecvData += new NetEvent(tts.RecvData);
       
       
    //命令控制循环
       while(true)
       {
       Console.Write(
    ">");
       
    string cmd=Console.ReadLine();
       
    //退出测试程序
       if(cmd.ToLower() == "exit")
       {
       
    break;
       }
       
    //停止服务器程序
       if(cmd.ToLower() == "stop")
       {
       svr.Stop();
       
       Console.WriteLine(
    "Server is Stop.");
       
    continue;
       }
       
    //运行服务器程序
       if(cmd.ToLower() == "start")
       {
       svr.Start();
       Console.WriteLine(
    "Server is listen{0}",
       svr.ServerSocket.LocalEndPoint.ToString());
       
    continue;
       }
       
    //察看服务器在线客户端数目和容量
       if(cmd.ToLower() == "count")
       {
       Console.WriteLine(
    "Current count of Client is {0}/{1}",
       svr.SessionCount,svr.Capacity);
       
    continue;
       }
       
    //发送数据到客户端格式:send [Session] [stringData]
       if(cmd.ToLower().IndexOf("send"!=-1)
       {
       cmd 
    = cmd.ToLower();
       
    string[] para = cmd.Split(' ');
       
    if(para.Length ==3)
       {
       
       Session client 
    = (Session)svr.SessionTable[ new SessionId( int.Parse
       (para[
    1]))];
       
    if(client !=null)
       {
       svr.Send(client, para[
    2]);
       }
       
    else
       {
       Console.WriteLine(
    "The Session is Null");
       }
       
       }
       
    else
       {
       Console.WriteLine(
    "Error Command");
       }
       
    continue;
       }
       
    //从服务器上踢掉一个客户端
       if(cmd.ToLower().IndexOf("kick"!=-1)
       {
       cmd 
    = cmd.ToLower();
       
    string[] para = cmd.Split(' ');
       
       
    if(para.Length ==2)
       {
       Session client 
    = (Session)svr.SessionTable[ new SessionId( int.Parse
       (para[
    1]))];
       
    if(client !=null)
       {
       svr.CloseSession(client);
       }
       
    else
       {
       Console.WriteLine(
    "The Session is Null");
       }
       }
       
    else
       {
       Console.WriteLine(
    "Error command");
       }
       
       
    continue;
       }
       
    //列出服务器上所有的客户端信息
       if(cmd.ToLower() == "list")
       {
       
    int i=0
       
    foreach( Session Client in svr.SessionTable.Values)
       {
       
    if(Client !=null)
       {
       i
    ++;
       
    string info = string.Format("{0} Client:{1} connected server Session:{2}. Socket Handle:{3}",
       i,
       Client.ClientSocket.RemoteEndPoint.ToString(),
       Client.ID,
       Client.ClientSocket.Handle);
       Console.WriteLine( info );
       }
       
    else
       {
       i
    ++;
       
    string info = string.Format("{0} null Client", i);
       Console.WriteLine(info);
       }
       }
       
    continue;
       
       }
       Console.WriteLine(
    "Unkown Command");
       }
    //end of while
       Console.WriteLine("End service");
       }
       
    catch(Exception ex)
       {
       Console.WriteLine(ex.ToString());
       }
       }
       
    void ClientConn(object sender, NetEventArgs e)
       {
       
    string info = string.Format("A Client:{0} connect server Session:{1}. Socket Handle:{2}",
       e.Client.ClientSocket.RemoteEndPoint.ToString(),
       e.Client.ID,e.Client.ClientSocket.Handle);
       Console.WriteLine( info );
       Console.Write(
    ">");
       }
       
       
    void ServerFull(object sender, NetEventArgs e)
       {
       
    string info = string.Format("Server is full.the Client:{0} is refused",
       e.Client.ClientSocket.RemoteEndPoint.ToString());
       
    //Must do it
       
    //服务器满了,必须关闭新来的客户端连接
       e.Client.Close();
       Console.WriteLine(info);
       Console.Write(
    ">");
       }
       
    void ClientClose(object sender, NetEventArgs e)
       {
       
    string info ;
       
    if( e.Client.TypeOfExit == Session.ExitType.ExceptionExit)
       {
       info
    = string.Format("A Client Session:{0} Exception Closed.",
       e.Client.ID);
       }
       
    else
       {
       info
    = string.Format("A Client Session:{0} Normal Closed.",
       e.Client.ID);
       }
       Console.WriteLine( info );
       Console.Write(
    ">");
       }
       
    void RecvData(object sender, NetEventArgs e)
       {
       
    string info = string.Format("recv data:{0} from:{1}.",e.Client.Datagram, e.Client);
       Console.WriteLine( info );
       TcpSvr svr 
    = (TcpSvr) sender;
       
    //测试把收到的数据返回给客户端
       svr.Send(e.Client, e.Client.Datagram);
       Console.Write(
    ">");
       
       }
      }
      }
    B.说明:
      使用命令来操作服务器
      exit 退出
      start 开始服务
      kick 关闭客户端
      send 发送数据
      list 列出所有客户端的状态
      count 客户端计数
      先启动服务运行start,等待客户端连接。
      然后可以使用list,count察看当前的连接状况
      每个事件都有相应函数,客户就在事件处理函数中处理自己的业务逻辑
      可以通过继承特化自己的服务器应用,基本的框架不变
      二.TcpCli的使用方法
      A.测试程序:
    using System;
      
    using Ibms.Net.TcpCSFramework;
      
    namespace Ibms.Test
      {
      
    /// <summary>
      
    /// TestTcpClient 的摘要说明。
      
    /// </summary>
      public class TestTcpClient
      {
       
    public TestTcpClient()
       {
       
    //
       
    // TODO: 在此处添加构造函数逻辑
       
    //
       }
       
    public static void Test()
       {
       Console.WriteLine(
    "Begin to Test TcpCli Class..");
       TestTcpClient test 
    = new TestTcpClient();
       TcpCli cli 
    = new TcpCli( new Coder(Coder.EncodingMothord.UTF8));
       cli.Resovlver 
    = new DatagramResolver("##");
       cli.ReceivedDatagram 
    += new NetEvent(test.RecvData);
       cli.DisConnectedServer 
    += new NetEvent(test.ClientClose);
       cli.ConnectedServer 
    += new NetEvent(test.ClientConn);
       
       
    try
       {
       
    //命令控制循环
       while(true)
       {
       Console.Write(
    ">");
       
    string cmd=Console.ReadLine();
       
    if(cmd.ToLower() == "exit")
       {
       
    break;
       }
       
    if(cmd.ToLower() == "close")
       {
       cli.Close();
       
       
    continue;
       }
       
    if(cmd.ToLower().IndexOf("conn")!=-1)
       {
       cmd 
    = cmd.ToLower();
       
    string[] para = cmd.Split(' ');
       
    if(para.Length ==3)
       {
       
       cli.Connect(para[
    1],int.Parse(para[2]));
       }
       
    else
       {
       Console.WriteLine(
    "Error Command");
       }
       
    continue;
       }
       
    if(cmd.ToLower().IndexOf("send"!=-1)
       {
       
       
       cmd 
    = cmd.ToLower();
       
    string[] para = cmd.Split(' ');
       
    if(para.Length ==2)
       {
       
       cli.Send(para[
    1]);
       
       }
       
    else
       {
       Console.WriteLine(
    "Error Command");
       }
       
    continue;
       }
       
       Console.WriteLine(
    "Unkown Command");
       }
    //end of while
       Console.WriteLine("End service");
       }
       
    catch(Exception ex)
       {
       Console.WriteLine(ex.ToString());
       }
       }
       
    void ClientConn(object sender, NetEventArgs e)
       {
       
    string info = string.Format("A Client:{0} connect server :{1}",e.Client,
       e.Client.ClientSocket.RemoteEndPoint.ToString());
       Console.WriteLine( info );
       Console.Write(
    ">");
       }
       
       
    void ClientClose(object sender, NetEventArgs e)
       {
       
    string info ;
       
    if( e.Client.TypeOfExit == Session.ExitType.ExceptionExit)
       {
       info
    = string.Format("A Client Session:{0} Exception Closed.",
       e.Client.ID);
       }
       
    else
       {
       info
    = string.Format("A Client Session:{0} Normal Closed.",
       e.Client.ID);
       }
       Console.WriteLine( info );
       Console.Write(
    ">");
       }
       
    void RecvData(object sender, NetEventArgs e)
       {
       
    string info = string.Format("recv data:{0} from:{1}.",e.Client.Datagram, e.Client);
       Console.WriteLine( info );
       
       Console.Write(
    ">");
       
       }
      }
      }

    B.说明:
    先建立连接,Conn 192.9.207.214 9050
    然后可以Send 数据
    最后关闭连接Close
    三.编码器
    如果你要加密你的报文,需要一个你自己的Coder
    从Coder类继承一个如MyCoder类,然后重载编码和解码函数。
    使用方法:
    TcpCli cli = new TcpCli( new MyCoder());
    就可以在客户端使用该编码器了。
    四.报文解析器
    与编码器同样的实现方法。

  • 相关阅读:
    HDOJ1024(最大M子段和)
    HDOJ1025(最长上升子序列)
    HDOJ1022(模拟栈)
    HDOJ(1018)
    HDOJ1238(string)
    HDOJ1015(简单深搜)
    HDOJ1016(标准dfs)
    Tabbar视图切换,返回上一视图,添加item
    页面转换方法
    网络状态判断
  • 原文地址:https://www.cnblogs.com/llcto/p/1583659.html
Copyright © 2011-2022 走看看