底层库
Net.Sz.CFramework
Net.Sz.CFramework 是我自己的底层库,是经过验证的底层库。
包含:
socket tcp协议,
socket http协议线程池,
线程模型,
任务模型,
定时器模型,
日志模块
脚本模块
一些辅助类
接下来一一介绍
这里是华丽丽的分割线
辅助类功能块
1 // 摘要: 2 // 获取当前时间和 1970-01-01 00:00:00 的时间差 3 // 为了和java一致使用的是 UTC 时间 4 public static long CurrentTimeMillis(); 5 // 6 // 摘要: 7 // 获取当前时间所表示的毫秒数 8 public static long CurrentTimeMillis(DateTime dt); 9 public static long CurrentTimeMillis_Java(); 10 // 11 // 摘要: 12 // 获取当前时间所表示的毫秒数 13 public static long CurrentTimeMillis_Java(DateTime dt); 14 // 15 // 摘要: 16 // 将毫秒数转化成当前时间 17 public static DateTime DateNow(long milliseconds); 18 public static DateTime DateNow_Java(long milliseconds); 19 // 20 // 摘要: 21 // yyyy-MM-dd HH:mm:ss:fff: 22 // 23 // 参数: 24 // d: 25 public static string NowString(DateTime d);
后面java函数是输出和java一直的时间函数
1 // 2 // 摘要: 3 // 验证活动是否结束 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59] 4 // 第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间, 5 // 每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如: “2015/2017”表示2015 6 // 或者 2017 7 public static bool VerifyConfigEndTimeStr(DateTime date, string timeStr); 8 9 // 10 // 摘要: 11 // 获取活动结束时间倒计时 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59] 12 // 第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间, 13 // 每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如: “2015/2017”表示2015 14 // 或者 2017 15 // 返回值 -1 表示永久过期,0 表示在时间规则内,大于 0 表示倒计时 16 public static long VerifyDateEndTime(string timeStr); 17 18 // 19 // 摘要: 20 // 获取开始倒计时 验证时间:[*][*][20/22][*][10:00-11:59/16:00-17:59] 21 // 第一个是年,,第二个是月,第三个是日期,第四个是星期,第五个是时间, 22 // 每一个参数,"-" 表示 到 如:“2015-2017”表示 2015 到 2017, "/" 表示 或者 如: “2015/2017”表示2015 23 // 或者 2017 24 // 返回值 -1 表示永久过期,0 表示在时间规则内,大于 0 表示倒计时 25 public static long VerifyDateTime(string timeStr);
时间匹配函数,看到这里后,请不要给我提quartz 因为我只会回答你不同的需求,不同的环境会有不同的使用情况
位运算辅助函数
1 Net.Sz.CFramework.Struct.EnumStatus status2 = new Net.Sz.CFramework.Struct.EnumStatus(1 << 1, 1 << 0);
使用方式和详解请看 状态机
接下来介绍日志组建
本日志组建支持大约输出日志信息的文件名函数名和行号
方法是异步处理的支持写入文件,文件写入格式是每天一个文件。
1 //是否显示控制台打印
2 Net.Sz.CFramework.Log.Logger.LOGCONSOLE = true;
3 //只支持三种格式。控制台输出,info级别和error级别
4 Net.Sz.CFramework.Log.Logger.LOGLEVEL = Net.Sz.CFramework.Log.ENUM_LOGLEVEL.DEBUG;
5
6 Net.Sz.CFramework.Log.Logger.Debug("{0}->{1}", 55, "test");
7 Net.Sz.CFramework.Log.Logger.Info("{0}->{1}", 55, "test");
8 Net.Sz.CFramework.Log.Logger.Error("{0}->{1}", 55, "test");
9
10 //只显示info
11 Net.Sz.CFramework.Log.Logger.LOGLEVEL = Net.Sz.CFramework.Log.ENUM_LOGLEVEL.INFO;
12
13 Net.Sz.CFramework.Log.Logger.Debug("{0}->{1}", 55, "test");
14 Net.Sz.CFramework.Log.Logger.Info("{0}->{1}", 55, "test");
15 Net.Sz.CFramework.Log.Logger.Error("{0}->{1}", 55, "test");
大约信息如下
[2016-03-30 15:03:13:9706: Debug:CApp1.Program, Main, 26] 55->test [2016-03-30 15:03:14:0496: Info :CApp1.Program, Main, 27] 55->test [2016-03-30 15:03:14:0536: Error:CApp1.Program, Main, 30] 55->test [2016-03-30 15:03:14:0536: Info :CApp1.Program, Main, 34] 55->test [2016-03-30 15:03:14:0536: Error:CApp1.Program, Main, 36] 55->test
线程模型.
这里包含了线程模型,任务模型和定时器任务模型
1 //是以一个线程执行任务的线程模型
2 long t1 = Net.Sz.CFramework.Threading.ThreadPool.GetThreadModel("test", 1);
3
4 //是以十个线程执行任务的线程模型
5 long t10 = Net.Sz.CFramework.Threading.ThreadPool.GetThreadModel("test", 10);
6
7 //创建一个简单任务
8 Net.Sz.CFramework.Threading.ThreadPool.AddTask(t1, new Net.Sz.CFramework.Threading.TaskModel_Action(() =>
9 {
10 Net.Sz.CFramework.Log.Logger.Debug("TaskModel_Action 简单任务");
11
12 }));
13
14 //创建一个简单的定时器任务,创建一个执行3次,每个2秒执行一次的任务
15 Net.Sz.CFramework.Threading.ThreadPool.AddTimerTask(t1, new Net.Sz.CFramework.Threading.TimerTask_Action(3, 2000, () =>
16 {
17 Net.Sz.CFramework.Log.Logger.Debug("TimerTask_Action 简单任务");
18
19 }));
输出
1 [2016-03-30 15:16:43:2129: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < 全局线程线程 > 2 [2016-03-30 15:16:43:3249: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread线程_1 > 3 [2016-03-30 15:16:43:3299: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread线程_2 > 4 [2016-03-30 15:16:43:3439: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] Back Thread 接手定时器任务 Net.Sz.CFramework.Threading.Timer.GlobTimerEvent 5 [2016-03-30 15:16:43:3589: Info :Net.Sz.CFramework.Threading.TimerThread, .ctor, 47] 初始化 < timer 线程 > 6 [2016-03-30 15:16:43:3719: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < test线程 > 7 [2016-03-30 15:16:43:3849: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_1 > 8 [2016-03-30 15:16:43:3899: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_2 > 9 [2016-03-30 15:16:43:4059: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_3 > 10 [2016-03-30 15:16:43:4099: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_4 > 11 [2016-03-30 15:16:43:4159: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_5 > 12 [2016-03-30 15:16:43:4249: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_6 > 13 [2016-03-30 15:16:43:4359: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_7 > 14 [2016-03-30 15:16:43:4399: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_8 > 15 [2016-03-30 15:16:43:4469: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_9 > 16 [2016-03-30 15:16:43:4559: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < test线程_10 > 17 [2016-03-30 15:16:43:4649: Debug:CApp1.Program, <Main>b__0, 23] TaskModel_Action 简单任务 18 [2016-03-30 15:16:43:4659: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] test 接手定时器任务 Net.Sz.CFramework.Threading.TimerTask_Action 19 [2016-03-30 15:16:43:4729: Debug:CApp1.Program, <Main>b__1, 30] TimerTask_Action 简单任务 20 [2016-03-30 15:16:45:4820: Debug:CApp1.Program, <Main>b__1, 30] TimerTask_Action 简单任务 21 [2016-03-30 15:16:47:4921: Debug:CApp1.Program, <Main>b__1, 30] TimerTask_Action 简单任务
Socket Tcp组建
tcp监听需要实现IIOSessionHandler接口
1 // 摘要:
2 // http监听处理
3 // @author 失足程序员
4 // @Blog http://www.cnblogs.com/ty408/
5 // @mail 492794628@qq.com
6 // @phone 13882122019
7 public interface IIOSessionHandler
8 {
9 // 摘要:
10 // 新建链接
11 //
12 // 参数:
13 // session:
14 void channelActive(IOSession session);
15 //
16 // 摘要:
17 // 链接闲置状态
18 //
19 // 参数:
20 // session:
21 void channelInactive(IOSession session);
22 //
23 // 摘要:
24 // 有消息,请注意消息是多线程处理的。也许你前一个消息没有处理完成,后一个消息已经来了
25 //
26 // 参数:
27 // session:
28 //
29 // buffer:
30 void channelRead(IOSession session, byte[] buffer);
31 //
32 // 摘要:
33 // 链接断开
34 //
35 // 参数:
36 // session:
37 void channelUnregistered(IOSession session, params string[] obj);
38 //
39 // 摘要:
40 // 链接发送异常
41 //
42 // 参数:
43 // session:
44 //
45 // ex:
46 void exceptionCaught(IOSession session, Exception ex);
47 }
1 //客户端和服务器都需要这个处理接口实现
2 Net.Sz.CFramework.Netty.NettyPool.SessionHandler = new MySessionHandler();
3 //创建对ip127.0.0.1端口9527的tcp监听,使用一个线程处理这个监听的io信息
4 Net.Sz.CFramework.Netty.NettyPool.AddTcpBind("127.0.0.1", 9527, 1);
5 //创建对服务器连接
6 Net.Sz.CFramework.Netty.Tcp.NettyClient client = new Net.Sz.CFramework.Netty.Tcp.NettyClient("127.0.0.1", 9527);
7 client.Connect();
需要特别注意public void channelRead(Net.Sz.CFramework.Netty.IOSession session, byte[] buffer)
这个函数收到的消息的字节数组是一个完整的独立包
1 #pragma once
2 #include "stdafx.h"
3 #include "BufferReader.h"
4 #include "BufferWriter.h"
5
6
7 using namespace System;
8
9 namespace Net{
10 namespace Sz{
11 namespace CFramework{
12 namespace Netty{
13 namespace Buffer{
14
15 using namespace System::IO;
16 using namespace System::Collections::Generic;
17
18 /// <summary>
19 /// 字节流书写器
20 /// <para>@author 失足程序员</para>
21 /// <para>@Blog http://www.cnblogs.com/ty408/</para>
22 /// <para>@mail 492794628@qq.com</para>
23 /// <para>@phone 13882122019</para>
24 /// </summary>
25 ref class DefaultMarshalEndian
26 {
27 //用于存储剩余未解析的字节数
28 private:
29 List<Byte>^ _LBuff = gcnew List<Byte>(2);
30
31 //字节数常量一个消息id4个字节
32 const long ConstLenght = 8L;
33 const short ConstStart1 = 0xaa;
34 const short ConstStart2 = 0xbb;
35
36 public:
37 List<array<Byte>^>^ Decoder(array<Byte>^ buff)
38 {
39 if (this->_LBuff->Count > 0)
40 {
41 //拷贝之前遗留的字节
42 this->_LBuff->AddRange(buff);
43 buff = this->_LBuff->ToArray();
44 this->_LBuff = gcnew List<Byte>(2);
45 }
46 List<array<Byte>^>^ list = gcnew List<array<Byte>^>();
47
48 BufferReader^ buffers = gcnew BufferReader(buff);
49
50 try
51 {
52 array<Byte>^ _buff;
53 Label_0073:
54
55 //判断本次解析的字节是否满足常量字节数
56 if ((buffers->BaseStream->Length - buffers->BaseStream->Position) < ConstLenght)
57 {
58 _buff = buffers->ReadBytes((int)(buffers->BaseStream->Length - buffers->BaseStream->Position));
59 this->_LBuff->AddRange(_buff);
60 }
61 else
62 {
63 short tmpStart1 = buffers->ReadInt16();
64 if (ConstStart1 == tmpStart1)//自定义头相同
65 {
66 short tmpStart2 = buffers->ReadInt16();
67 if (ConstStart2 == tmpStart2)//自定义头相同
68 {
69 long offset = buffers->ReadInt32();
70 //剩余字节数大于本次需要读取的字节数
71 if (offset <= (buffers->BaseStream->Length - buffers->BaseStream->Position))
72 {
73 _buff = buffers->ReadBytes((int)(offset));
74 list->Add(_buff);
75 goto Label_0073;
76 }
77 else
78 {
79 //剩余字节数刚好小于本次读取的字节数 存起来,等待接受剩余字节数一起解析
80 buffers->BaseStream->Seek(ConstLenght, System::IO::SeekOrigin::Current);
81 _buff = buffers->ReadBytes((int)(buffers->BaseStream->Length - buffers->BaseStream->Position));
82 this->_LBuff->AddRange(_buff);
83 }
84 }
85 else
86 {
87 //往前推三个字节
88 buffers->BaseStream->Seek(-3, System::IO::SeekOrigin::Current);
89 goto Label_0073;
90 }
91 }
92 else
93 {
94 //往前推一个字节
95 buffers->BaseStream->Seek(-1, System::IO::SeekOrigin::Current);
96 goto Label_0073;
97 }
98 }
99 }
100 catch (Exception^){}
101 finally
102 {
103 buffers->Close();
104 delete buffers;
105 }
106 return list;
107 }
108
109 void Encoder(array<Byte>^ msgBuffer, BufferWriter^ %outBuf)
110 {
111 outBuf->Write(ConstStart1);
112 outBuf->Write(ConstStart2);
113 if (msgBuffer != nullptr)
114 {
115 outBuf->Write((Int32)(msgBuffer->Length));
116 outBuf->Write(msgBuffer);
117 }
118 else
119 {
120 outBuf->Write((Int32)0);
121 }
122 }
123
124 };
125 }
126 }
127 }
128 }
129 }
解码和编码器
1 [2016-03-30 15:28:55:5178: Info :Net.Sz.CFramework.Netty.Tcp.NettyServer, .ctor, 61] Start Listen Tcp Socket -> 127.0.0.1:9527 2 [2016-03-30 15:28:55:6028: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < 全局线程线程 > 3 [2016-03-30 15:28:55:6258: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread线程_1 > 4 [2016-03-30 15:28:55:6318: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 151] 初始化 < Back Thread线程_2 > 5 [2016-03-30 15:28:55:6458: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] Back Thread 接手定时器任务 Net.Sz.CFramework.Threading.Timer.GlobTimerEvent 6 [2016-03-30 15:28:55:6648: Info :Net.Sz.CFramework.Threading.TimerThread, .ctor, 47] 初始化 < timer 线程 > 7 [2016-03-30 15:28:55:6798: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < Netty Session Pool Thread:127.0.0.1:9527线程 > 8 [2016-03-30 15:28:55:7078: Info :Net.Sz.CFramework.Threading.ThreadModel, .ctor, 149] 初始化 < Netty Session Pool Thread线程 > 9 [2016-03-30 15:28:55:7098: Debug:Net.Sz.CFramework.Threading.ThreadModel, AddTimerTask, 200] Netty Session Pool Thread 接手定时器任务 Net.Sz.CFramework.Netty.CheckIOSessionTimerTask 10 [2016-03-30 15:28:55:7188: Debug:Net.Sz.CFramework.Netty.Tcp.NettyClient, Connect, 48] Try Connect Tcp Socket Remote:127.0.0.1:9527 11 [2016-03-30 15:28:55:7388: Debug:Net.Sz.CFramework.Netty.Tcp.NettyClient, Connect, 51] Connect Tcp Socket Remote Socket RemoteEndPoint:127.0.0.1:9527 LocalEndPoint:127.0.0.1:17669 12 [2016-03-30 15:28:55:7468: Info :Net.Sz.CFramework.Netty.Tcp.NettyServer, AcceptAsync_Async, 43] Create Tcp Socket Remote Socket LocalEndPoint:127.0.0.1:9527 RemoteEndPoint:127.0.0.1:17669
Socket Http监听
需要实现
1 // 摘要:
2 // http监听处理
3 // @author 失足程序员
4 // @Blog http://www.cnblogs.com/ty408/
5 // @mail 492794628@qq.com
6 // @phone 13882122019
7 public interface IHttpHandler : IBaseScript
8 {
9 // 摘要:
10 // 并发处理的
11 //
12 // 参数:
13 // session:
14 // 连接对象
15 void Action(HttpSession session);
16 }
1 class Program
2 {
3
4 static void Main(string[] args)
5 {
6 //创建login目录的监听,处理程序是LoginHttpHandler,单线程处理请求
7 Net.Sz.CFramework.Netty.NettyPool.AddHttpBind("127.0.0.1", 9527, "login", new LoginHttpHandler(), 1);
8 Console.ReadLine();
9 }
10 }
11 class LoginHttpHandler : Net.Sz.CFramework.Netty.Http.IHttpHandler
12 {
13 public void Action(Net.Sz.CFramework.Netty.Http.HttpSession session)
14 {
15 session.WriteSuccess();
16 session.AddBody("Login OK");
17 session.WriteFlush();
18 }
19 }

脚步使用功能
使用脚步功能,C#的文件类,*.cs文件类
如果是实现IBaseScript可以放到脚步管理器里面进行查找
如果实现IInitBaseScript接口执行初始化函数;如果没有只实现IInitBaseScript不会放到脚步管理,
// 摘要:
// 脚本基类
// @author 失足程序员
// @Blog http://www.cnblogs.com/ty408/
// @mail 492794628@qq.com
// @phone 13882122019
public interface IBaseScript
// 摘要:
// 脚本基类
// 执行init初始化信息
// PS:实现这个接口不会放到脚步缓存集合中,如果需要请实现 IBaseScript
// @author 失足程序员
// @Blog http://www.cnblogs.com/ty408/
// @mail 492794628@qq.com
// @phone 13882122019
public interface IInitBaseScript
{
// 摘要:
// 卸载脚本
void InitScript();
}
//传入文件路径,可以是相对路径也可以是绝对路径,后面可以传入需要引入的dll文件或者exe文件用于编译和加载
ScriptManager.LoadCSharpFile(new String[] { "" }, "");
这里以我的游戏程序距离
public static List<string> LoadScript()
{
return ScriptManager.LoadCSharpFile(new string[] { "../../../../Net.Sz.Game.MMOGame.GameServer.Scripts/Src" },
"protobuf-net.dll",
"EntityFramework.dll",
"MySql.Data.dll",
"Net.Sz.Framework.DB.dll",
"MySql.Data.Entity.EF6.dll",
"Net.Sz.Game.MMOGame.GameMessages.dll",
"Net.Sz.Game.MMOGame.GameModel.dll"
);
}
public static Net.Sz.CFramework.Script.ScriptPool ScriptManager { get; private set; }
/// <summary>
///
/// </summary>
public static void Start()
{
Net.Sz.CFramework.Struct.SzExtensions.Console_Show("Server", false, true);
try
{
LoadScript();
}
catch (Exception)
{
throw;
}
}

这是我的底层库支持。望各位大仙多多指教!
对应提供下载.
java 版本的源码下载
/** * * @author 失足程序员 * @Blog http://www.cnblogs.com/ty408/ * @mail 492794628@qq.com * @phone 13882122019 * */ 跪求保留标示符 本程序猿所有博客园相关全套源码奉献 淘宝SVN。特别鸣谢淘宝SVN提供免费仓储。 http://code.taobao.org/svn/flynetwork_csharp/trunk/Flynetwork/BlogTest
