C#异步Socket实现TCP网络服务的通讯构架2
作者: 不详
编辑: 海韵 发布日期: 2007-01-31 00:00:00 点击量: 8781
来源: haiyun.net
使用方法 | |
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()); 就可以在客户端使用该编码器了。 四.报文解析器 与编码器同样的实现方法。 |