您的位置:首页 > 理论基础 > 计算机网络

[转]在C#中使用异步Socket编程实现TCP网络服务的C/S的通讯构架(二)

2009-10-15 09:15 1041 查看
一.TcpSvr的使用方法
  A. div:eq(0) > div:eq(3) > table:eq(2) > tbody:eq(0) > tr:eq(0) > td:eq(0) > div:eq(0) > #content:eq(0) > br:eq(0)" offset="4" anchortype="previous" jquery1232509146750="44">测试程序:

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察看当前的连接状况
  每个事件都有相应函数,客户就在 div:eq(0) > div:eq(3) > table:eq(2) > tbody:eq(0) > tr:eq(0) > td:eq(0) > div:eq(0) > #content:eq(0) > br:eq(214)" offset="17" anchortype="previous" jquery1232509146750="41">事件处理函数

中处理自己的业务逻辑
  可以通过继承 div:eq(0) > div:eq(3) > table:eq(2) > tbody:eq(0) > tr:eq(0) > td:eq(0) > div:eq(0) > #content:eq(0) > br:eq(215)" offset="8" anchortype="previous" jquery1232509146750="40">特化

自己的服务器应用,基本的框架不变
  二.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
三. div:eq(0) > div:eq(3) > table:eq(2) > tbody:eq(0) > tr:eq(0) > td:eq(0) > div:eq(0) > #content:eq(0) > br:eq(341)" offset="4" anchortype="previous" jquery1232509146750="43">编码器
如果你要加密你的 div:eq(0) > div:eq(3) > table:eq(2) > tbody:eq(0) > tr:eq(0) > td:eq(0) > div:eq(0) > #content:eq(0) > br:eq(342)" offset="10" anchortype="previous" jquery1232509146750="42">报文,需要一个你自己的Coder
从Coder类继承一个如MyCoder类,然后重载编码和解码函数。
使用方法:
TcpCli cli = new TcpCli( new MyCoder());
就可以在客户端使用该编码器了。
四.报文解析器
与编码器同样的实现方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐