C# C/S模式的服务器端如何判断客户端发来的是什么信息 c/s网络编程c# 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 比如说你使用 NewtoneSoft.Json 来进行 json 跟 .net 内部对象的转换处理。假设我们收到了一个字符串{ "SeqNum" : 10023, "CmdType“ : "EnteringRoom", "Content" : { "RoomId" : "1293883", "Account" : "abc", "Pwd" : "8899ksdkf82", "Expire" : 5 }}这里,首先,所有的命令都有 SeqNum 表示序号,"Type"表示命令类型,"Content” 表示具体的命令体内容。不同命令,其格式上就是 Content 部分 有所不同。解析时,首先使用 var x = JObject.Parse(str); 来得到整个命令,然后 根据 (string)x["CmdType“] 的值,到你的命令字典中找到对应的具体命令(是一个class)在 .net 程序内部声明 Type。var cmd = x["Content"].ToObject(type);现在,我们就把传过来的命令解析出一个独立的 EnteringRoom 类型对象,并且赋值给变量 cmd 了。执行命令更为简单。执行命令就是“输入object,输出object”的函数。在你的程序一开始,需要声明public static Dictionary<Type, Func<object,object>> commands = new Dictionary<Type, Func<object,object>>(); 的一个集合,并且在程序一开始注册给这个集合。例如private object Enter(object cmd){ ....}commands.Add(typeof(EnteringRoom, Enter); //注册 Enter 方法负责处理以 EnteringRoom 类型命令那么根据上述cmd,就可以找到处理程序并进行处理,例如Func<object,object> p;object result;if(commands.TryGetCalue(cmd.GetType(), out p)) result = p(cmd);else throw new Exception(string.Format("找不到 {0} 的命令处理程序。", cmd.GetType().FullName)); 得到返回值之后,再把它封装为一个完整的命令,返回给发送端即可。例如我们规定返回信息的 SeqNum编号为负数表示返回,就可以写var y = new Commnd{ SeqNum = -(int)x["SeqNum"], CmdType = result.GetType().Name, Content = JObject.FromObject(result).ToString() };最后把这个命令 y 进行 json 序列化,发送给对方作为返回消息。 最后我要补充一点儿,上面说的是逻辑上的核心设计概念,这部分是最有特点的,每一个系统的设计方式可以不一样(我们的肯定也比这个复杂一点)。这里并没有什么“包”的概念。因为“包”是一个相对来说没有技术含量的封装层,而上面说的都是包承载的内容用于整个业务处理的流程。对于没有什么技术含量的那层“封装”,才是针对简单的 byte[] 传递的。在你接收数据时,总是会“粘包”的,因此我们可以这样规定包的格式(举例):1. 前4个字节表示整个包的长度;2. 然后是上述 y 内容的 json 字符串。这就行了。所以“包”本身没有技术含量,不过就是用来让你接收端不会“粘包”的。真正有技术含量的函是对于包中的内容的解析机制。 嗯,上面我的例子中有一行代码应该是写错了, Content = JObject.FromObject(result).ToString()应该写为 Content = JObject.FromObject(result)才对,因为我在举一开始的接收端的例子时,对于 Content 属性,是做为 JObject 类型,而不是作为 string 类型处理的。 先决定C和S用什么协议链接。最简单的,S就是数据库,C直接用ADO.NET访问数据库就好了。其次,S如果你是个Web站点,那么就是用http,不嫌麻烦(或者为了兼容已有网站)你的C就模拟http提交的表单来和web站点交互,当然也可以自己定义首发的内容,如楼上那些方式。也可以用现成的WebService/WCF来交互处理。最麻烦,某些场景下也是必须的就是用TCP/UDP通信,这样你自己定义两段收发的命令就好了。比如C发过去1,S就知道要注册用户了。 C#生成Word文档时如何做到时时可见生成过程 C#怎么让textbox的值每秒存一次,存在txt里,用线程怎么实现? asp.net中可以在实体类中用Response来输出图像吗? 如何捕获所有可能出现的异常? RDLC报表 发布报错 100分 C# 如何屏蔽 Win 组合键 求一个可访问的FTP地址 这个正则表达式 请来帮忙,先谢了 新建的C#.NET编程 群 欢迎大家畅所预言 C#的winform中,一panel加载万能播放器,支持对flv等的播放 关于.net控制台连接oracle遇到的问题
{ "SeqNum" : 10023,
"CmdType“ : "EnteringRoom",
"Content" : { "RoomId" : "1293883",
"Account" : "abc",
"Pwd" : "8899ksdkf82",
"Expire" : 5
}
}这里,首先,所有的命令都有 SeqNum 表示序号,"Type"表示命令类型,"Content” 表示具体的命令体内容。不同命令,其格式上就是 Content 部分 有所不同。解析时,首先使用 var x = JObject.Parse(str); 来得到整个命令,然后 根据 (string)x["CmdType“] 的值,到你的命令字典中找到对应的具体命令(是一个class)在 .net 程序内部声明 Type。
var cmd = x["Content"].ToObject(type);
现在,我们就把传过来的命令解析出一个独立的 EnteringRoom 类型对象,并且赋值给变量 cmd 了。执行命令更为简单。执行命令就是“输入object,输出object”的函数。在你的程序一开始,需要声明public static Dictionary<Type, Func<object,object>> commands = new Dictionary<Type, Func<object,object>>(); 的一个集合,并且在程序一开始注册给这个集合。例如private object Enter(object cmd)
{
....
}commands.Add(typeof(EnteringRoom, Enter); //注册 Enter 方法负责处理以 EnteringRoom 类型命令
那么根据上述cmd,就可以找到处理程序并进行处理,例如Func<object,object> p;
object result;
if(commands.TryGetCalue(cmd.GetType(), out p))
result = p(cmd);
else
throw new Exception(string.Format("找不到 {0} 的命令处理程序。", cmd.GetType().FullName));
得到返回值之后,再把它封装为一个完整的命令,返回给发送端即可。例如我们规定返回信息的 SeqNum编号为负数表示返回,就可以写var y = new Commnd{
SeqNum = -(int)x["SeqNum"],
CmdType = result.GetType().Name,
Content = JObject.FromObject(result).ToString()
};
最后把这个命令 y 进行 json 序列化,发送给对方作为返回消息。
Content = JObject.FromObject(result).ToString()
应该写为
Content = JObject.FromObject(result)
才对,因为我在举一开始的接收端的例子时,对于 Content 属性,是做为 JObject 类型,而不是作为 string 类型处理的。
最简单的,S就是数据库,C直接用ADO.NET访问数据库就好了。
其次,S如果你是个Web站点,那么就是用http,不嫌麻烦(或者为了兼容已有网站)你的C就模拟http提交的表单来和web站点交互,当然也可以自己定义首发的内容,如楼上那些方式。也可以用现成的WebService/WCF来交互处理。
最麻烦,某些场景下也是必须的就是用TCP/UDP通信,这样你自己定义两段收发的命令就好了。比如C发过去1,S就知道要注册用户了。