[转]在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());
就可以在客户端使用该编码器了。
四.报文解析器
与编码器同样的实现方法。

转载于:https://www.cnblogs.com/llcto/archive/2009/10/15/1583659.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值