分类 📝烂笔头 下的文章 - 社畜猿
首页
🕒归档
📖留言板
💌关于
搜 索
1
我的小世界——博客上线啦
1,323 阅读
2
写于小程序上线之前
1,209 阅读
3
近期准备上线本站小程序
868 阅读
4
利用CSS3制作旋转3D立方体
742 阅读
5
RabbitMq C# .NET 接收广播 消费者 订阅者 简单使用 ~~
381 阅读
💯C#
🐘PHP
📝烂笔头
♉侃侃
登录
搜 索
标签搜索
React Native
rabbmitmq
thinkphp
Mysql
Typecho
socket
uniapp
tinkphp
php
echart
C语言
程序猿
累计撰写
130
篇文章
累计收到
17
条评论
首页
栏目
💯C#
🐘PHP
📝烂笔头
♉侃侃
页面
🕒归档
📖留言板
💌关于
用户登录
登录
找到
28
篇与
相关的结果
2022-09-16
Javascript清除浏览器所有的cookie
Javascript清除浏览器所有的cookie
2022年09月16日
21 阅读
0 评论
2 点赞
2022-02-16
C#操作SQLite数据库
1、SQLite 简介SQLite是一个开源、免费的小型RDBMS(关系型数据库),能独立运行、无服务器、零配置、支持事物,用C实现,内存占用较小,支持绝大数的SQL92标准。这意味着与其他数据库一样,您不需要在系统中配置。SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。2、 为什么选择 SQLite?不需要一个单独的服务器进程或操作的系统(无服务器的)。SQLite 不需要配置,这意味着不需要安装或管理。一个完整的 SQLite 数据库是存储在一个单一的跨平台的磁盘文件。SQLite 是非常小的,是轻量级的,完全配置时小于 400KiB,省略可选功能配置时小于250KiB。SQLite 是自给自足的,这意味着不需要任何外部的依赖。SQLite 事务是完全兼容 ACID 的,允许从多个进程或线程安全访问。SQLite 支持 SQL92(SQL2)标准的大多数查询语言的功能。SQLite 使用 ANSI-C 编写的,并提供了简单和易于使用的 API。SQLite 可在 UNIX(Linux, Mac OS-X, Android, iOS)和 Windows(Win32, WinCE, WinRT)中运行。3、C#操作数据库基本方式:Data Source=c:mydb.db;Version=3;Nuget 直接搜索安装:System.Data.SQLite.Core代码实例using System; using System.Data.SQLite; namespace SQLiteSamples { class Program { //数据库连接 SQLiteConnection m_dbConnection; static void Main(string[] args) { Program p = new Program(); } public Program() { createNewDatabase(); connectToDatabase(); createTable(); fillTable(); printHighscores(); } //创建一个空的数据库 void createNewDatabase() { SQLiteConnection.CreateFile("MyDatabase.db");//可以不要此句 } //创建一个连接到指定数据库 void connectToDatabase() { m_dbConnection = new SQLiteConnection("Data Source=MyDatabase.db;Version=3;");//没有数据库则自动创建 m_dbConnection.Open(); } //在指定数据库中创建一个table void createTable() { string sql = "create table if not exists highscores (name varchar(20), score int)"; SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection); command.ExecuteNonQuery(); } //插入一些数据 void fillTable() { string sql = "insert into highscores (name, score) values ('Me', 3000)"; SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection); command.ExecuteNonQuery(); sql = "insert into highscores (name, score) values ('Myself', 6000)"; command = new SQLiteCommand(sql, m_dbConnection); command.ExecuteNonQuery(); sql = "insert into highscores (name, score) values ('And I', 9001)"; command = new SQLiteCommand(sql, m_dbConnection); command.ExecuteNonQuery(); } //使用sql查询语句,并显示结果 void printHighscores() { string sql = "select * from highscores order by score desc"; SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection); SQLiteDataReader reader = command.ExecuteReader(); while (reader.Read()) Console.WriteLine("Name: " + reader["name"] + "\tScore: " + reader["score"]); Console.ReadLine(); } } }
2022年02月16日
238 阅读
0 评论
0 点赞
2021-12-08
C# Find() 和FindIndex()的用法:找出满足集合List<char>特定条件的字符。
C# Find() 和FindIndex()的用法
2021年12月08日
98 阅读
0 评论
1 点赞
2021-11-23
C#—简单的tcp服务端
简单的tcp服务端代码如下private static TcpListener tcpListener; private static Thread listenThread; static void Main(string[] args) { Console.WriteLine("Welcome!"); Console.WriteLine(DateTime.Now); tcpListener = new TcpListener(IPAddress.Any, 8888); listenThread = new Thread(new ThreadStart(ListenForClients)); listenThread.Start(); try { } catch (Exception ex) { Console.WriteLine(ex.ToString()); } }private static void ListenForClients() { tcpListener.Start(); while (true) { TcpClient client = tcpListener.AcceptTcpClient(); Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClientComm)); clientThread.Start(client); } }private static void HandleClientComm(object client) { TcpClient tcpClient = (TcpClient)client; Console.WriteLine("客户端 @[] 已连接 @", tcpClient.Client.RemoteEndPoint, DateTime.Now.ToString()); NetworkStream clientStream = tcpClient.GetStream(); byte[] cmdmsg = new byte[1024]; while (true) { try { bytesRead = clientStream.Read(cmdmsg, 0, cmdmsg.Length); } catch { Console.WriteLine("Error:receive msg error"); break; } if (bytesRead == 0) { //the client has disconnected from the server Console.WriteLine("客户端 @[] 离线 @", tcpClient.Client.RemoteEndPoint, DateTime.Now.ToString()); break; } } }
2021年11月23日
43 阅读
0 评论
0 点赞
2021-10-27
.NET Core简单读取json配置文件
Nuget 类库引用Microsoft.Extensions.Configuration Microsoft.Extensions.Configuration.Jsonjson 文件 demo{ "name": "wen", "age": 26, "family": { "mother": { "name": "娘", "age": 55 }, "father": { "name": "爹", "age": 56 } } } using System; using System.IO; using Microsoft.Extensions.Configuration; namespace Demo { class Program { static void Main(string[] args) { //添加 json 文件路径 var builder = new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile("appsettings.json"); //创建配置根对象 var configurationRoot = builder.Build(); //取配置根下的 name 部分 var nameSection = configurationRoot.GetSection("name"); //取配置根下的 family 部分 var familySection = configurationRoot.GetSection("family"); //取 family 部分下的 mother 部分下的 name 部分 var motherNameSection = familySection.GetSection("mother").GetSection("name"); //取 family 部分下的 father 部分下的 age 部分 var fatherAgeSection = familySection.GetSection("father").GetSection("age"); //Value 为文本值 Console.WriteLine($"name: "); Console.WriteLine($"motherName: "); Console.WriteLine($"fatherAge: "); Console.Read(); } } }
2021年10月27日
55 阅读
0 评论
1 点赞
2021-09-13
雪花ID Snowflake .Net版—分布式唯一ID
先抄个雪花ID介绍,雪花算法:雪花ID是用一个64位的整形数字来做ID,对应.net中的long,数据库中的bigint,雪花算法的原始版本是scala版,用于生成分布式ID(纯数字,时间顺序),订单编号等。自增ID:对于数据敏感场景不宜使用,且不适合于分布式场景。 GUID:采用无意义字符串,数据量增大时造成访问过慢,且不宜排序。算法描述:最高位是符号位,始终为0,不可用。41位的时间序列,精确到毫秒级,41位的长度可以使用69年。时间位还有一个很重要的作用是可以根据时间进行排序。10位的机器标识,10位的长度最多支持部署1024个节点。12位的计数序列号,序列号即一系列的自增id,可以支持同一节点同一毫秒生成多个ID序号,12位的计数序列号支持每个节点每毫秒产生4096个ID序号。雪花ID严重依赖系统当前时间,当系统时间被人为反后调整时,算法会出问题,可能会出重复ID.Snowflake原算法是在检测到系统时间被回调后直接抛异常.本代码在时钟回拨后,会将生成的ID时间戳停留在最后一次时间戳上(每当序列溢出时会往前走一毫秒),等待系统时间追上后即可以避过时钟回拨问题.这种处理方式的优点是时钟回拨后不会异常,能一直生成出雪花ID,但缺点是雪花ID中的时间戳不是系统的当前时间,会是回拨前的最后记录的一次时间戳,但相差也不大.不知道有没有什么生产系统会对这个时间戳要求非常严格,无法使用这种补救方式的?当然停掉系统后的时钟回拨是无法处理的,这种还是会有可能出现重复ID的.介绍完毕,下面直接上源码吧,,本源码除了生成雪花ID外,还提供解析雪花ID的方法.using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; namespace snowflake_Id { class Program { static void Main(string[] args) { var ids = new List<long>(); var idwork = new SnowflakeId(15, 3); for (var i = 0; i < 100; i++) { var idTest = idwork.NextId(); ids.Add(idTest); } foreach (var id in ids) { var idStr = SnowflakeId.AnalyzeId(id); Console.WriteLine("雪花ID:" + id + "\t\b解析-> " + idStr); } return; var watch = Stopwatch.StartNew(); System.Threading.Tasks.Parallel.For(0, 8, i => { for (var j = 0; j < 100000; j++) { var id = idwork.NextId(); lock (ids) { ids.Add(id); } } }); Console.WriteLine(ids.Count+ "个Id生成完毕,耗时:" + watch.ElapsedMilliseconds); //return; System.Threading.Tasks.Parallel.For(0, ids.Count, (i, state) => { for (var j = i+1; j < ids.Count; j++) { if (ids[i] == ids[j]) { Console.WriteLine("有重复项:" + ids[i]); state.Stop(); } } }); Console.WriteLine("重复项检查完毕,耗时:" + watch.ElapsedMilliseconds); Console.WriteLine("fineshed"); } } } /// <summary> /// 雪花ID /// Twitter_Snowflake /// SnowFlake的结构如下(每部分用-分开) /// 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 /// 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0 /// 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截)得到的值), /// 41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69 /// 这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。 /// 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId /// 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号 /// 总共加起来刚好64位,为一个Long型。 /// SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分), /// 并且效率较高,经测试,SnowFlake单机每秒都能够产生出极限4,096,000个ID来 /// </summary> public class SnowflakeId { // 开始时间截((new DateTime(2020, 1, 1, 0, 0, 0, DateTimeKind.Utc)-Jan1st1970).TotalMilliseconds) private const long twepoch = 1577836800000L; // 机器id所占的位数 private const int workerIdBits = 5; // 数据标识id所占的位数 private const int datacenterIdBits = 5; // 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) private const long maxWorkerId = -1L ^ (-1L << workerIdBits); // 支持的最大数据标识id,结果是31 private const long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); // 序列在id中占的位数 private const int sequenceBits = 12; // 数据标识id向左移17位(12+5) private const int datacenterIdShift = sequenceBits + workerIdBits; // 机器ID向左移12位 private const int workerIdShift = sequenceBits; // 时间截向左移22位(5+5+12) private const int timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; // 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) private const long sequenceMask = -1L ^ (-1L << sequenceBits); // 数据中心ID(0~31) public long datacenterId // 工作机器ID(0~31) public long workerId // 毫秒内序列(0~4095) public long sequence // 上次生成ID的时间截 public long lastTimestamp /// <summary> /// 雪花ID /// </summary> /// <param name="datacenterId">数据中心ID</param> /// <param name="workerId">工作机器ID</param> public SnowflakeId(long datacenterId,long workerId ) { if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new Exception(string.Format("datacenter Id can't be greater than or less than 0", maxDatacenterId)); } if (workerId > maxWorkerId || workerId < 0) { throw new Exception(string.Format("worker Id can't be greater than or less than 0", maxWorkerId)); } this.workerId = workerId; this.datacenterId = datacenterId; this.sequence = 0L; this.lastTimestamp = -1L; } /// <summary> /// 获得下一个ID /// </summary> /// <returns></returns> public long NextId() { lock (this) { long timestamp = GetCurrentTimestamp(); if (timestamp > lastTimestamp) //时间戳改变,毫秒内序列重置 { sequence = 0L; } else if (timestamp == lastTimestamp) //如果是同一时间生成的,则进行毫秒内序列 { sequence = (sequence + 1) & sequenceMask; if (sequence == 0) //毫秒内序列溢出 { timestamp = GetNextTimestamp(lastTimestamp); //阻塞到下一个毫秒,获得新的时间戳 } } else //当前时间小于上一次ID生成的时间戳,证明系统时钟被回拨,此时需要做回拨处理 { sequence = (sequence + 1) & sequenceMask; if (sequence > 0) { timestamp = lastTimestamp; //停留在最后一次时间戳上,等待系统时间追上后即完全度过了时钟回拨问题。 } else //毫秒内序列溢出 { timestamp = lastTimestamp + 1; //直接进位到下一个毫秒 } //throw new Exception(string.Format("Clock moved backwards. Refusing to generate id for milliseconds", lastTimestamp - timestamp)); } lastTimestamp = timestamp; //上次生成ID的时间截 //移位并通过或运算拼到一起组成64位的ID var id= ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence; return id; } } /// <summary> /// 解析雪花ID /// </summary> /// <returns></returns> public static string AnalyzeId(long Id) { StringBuilder sb = new StringBuilder(); var timestamp = (Id >> timestampLeftShift) ; var time = Jan1st1970.AddMilliseconds(timestamp + twepoch); sb.Append(time.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss:fff")); var datacenterId = (Id ^ (timestamp << timestampLeftShift)) >> datacenterIdShift; sb.Append("_" + datacenterId); var workerId = (Id ^ ((timestamp << timestampLeftShift) | (datacenterId << datacenterIdShift))) >> workerIdShift; sb.Append("_" + workerId); var sequence = Id & sequenceMask; sb.Append("_" + sequence); return sb.ToString(); } /// <summary> /// 阻塞到下一个毫秒,直到获得新的时间戳 /// </summary> /// <param name="lastTimestamp">上次生成ID的时间截</param> /// <returns>当前时间戳</returns> private static long GetNextTimestamp(long lastTimestamp) { long timestamp = GetCurrentTimestamp(); while (timestamp <= lastTimestamp) { timestamp = GetCurrentTimestamp(); } return timestamp; } /// <summary> /// 获取当前时间戳 /// </summary> /// <returns></returns> private static long GetCurrentTimestamp() { return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds; } private static readonly DateTime Jan1st1970 = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); }
2021年09月13日
77 阅读
1 评论
1 点赞
2021-07-12
c# 连接mysql关闭清空缓冲池—记录
c# 连接mysql关闭清空缓冲池
2021年07月12日
22 阅读
0 评论
1 点赞
2021-03-17
Socket 循环接收消息 粘包 半包(C#)
这两天在学习socket收发消息的问题,学到了新知识1、对于一次接收到大于接收缓存的消息,并且连续接收消息,两段消息可能同时被接受到一端缓存中,叫粘包;2、收到的消息不足一个接收缓存,交半包; 程序的几个注意点:1、必须要循环接收消息;2、消息头必须要有长度标志字节(这里是用的前四个字节来保存实际消息体的长度);3、除了接收缓存rev之外还需要一个cache缓存byte[] ,用来保存一条完整的消息;4、cache缓存可能不足一个接收缓存,那后面不足的会有0 补充 ,半包;5、cache缓存 可能刚好一个接收缓存,并且包含>= 1个完整消息(等于的时候无粘包,大于的时候有粘包);6、cache缓存 大于一个接收缓存,这里需要循环接收(用长度标志字节来判断),直到接收到 >= 一个完整消息,还是5、的情况;7、接受完一个完整消息后,需要清空缓存,或者将有粘包的字节重新拷贝到cache缓存;Socket soc = obj as Socket; int recvlen = 0; byte[] cacheBuf = null; byte[] recvBuf = new byte[100]; if (soc != null) { while ((recvlen = soc.Receive(recvBuf)) > 0) { if (cacheBuf == null) { cacheBuf = new byte[recvlen]; Array.Copy(recvBuf, cacheBuf, recvlen); } else { byte[] t = new byte[cacheBuf.Length + recvlen]; Array.Copy(cacheBuf, t, cacheBuf.Length); Array.Copy(recvBuf, 0, t, cacheBuf.Length, recvlen); cacheBuf = t; } if (cacheBuf.Length <= 4) continue; int msgl = BitConverter.ToInt32(cacheBuf, 0); while (cacheBuf!=null && msgl + 4 <= cacheBuf.Length) { byte[] msgbyte = new byte[msgl]; Array.Copy(cacheBuf, 4, msgbyte, 0, msgl); test(msgbyte,soc);//拿到完整消息,具体消息操作 if (msgl + 4 == cacheBuf.Length) { cacheBuf = null; } else { byte[] tmpByte = new byte[cacheBuf.Length - msgl - 4]; Array.Copy(cacheBuf, msgl + 4, tmpByte, 0, cacheBuf.Length - msgl - 4); cacheBuf = tmpByte; } } } }
2021年03月17日
142 阅读
2 评论
4 点赞
2021-03-08
数据库管理工具Navicat Premium 15 永久激活破解版
[1]Navicat premium是一款数据库管理工具,是一个可多重连线资料库的管理工具,它可以让你以单一程式同时连线到 MySQL、SQLite、Oracle 及 PostgreSQL 资料库,让管理不同类型的资料库更加的方便。最新版的Navicat Premium 16 已经发布了。前往Navicat官网下载最新的版本官网下载地址:https://www.navicat.com.cn/download/navicat-premium激活工具链接:https://pan.baidu.com/s/1ogMuj_iYCPtY4eyFCWNIJA提取码:6666下载好后选择安装路径后直接下一步傻瓜式安装即可。使用激活工具激活,双击打开此处一定要断网此处一定要断网此处一定要断网此处一定要断网选择安装目录(目录一定要在navicat安装的根目录下,也就是instantclient_11_2文件夹的上一级)点击Patch然后点击是,请勿选择否,否则需要卸载,重装再来一次.打开navicat的注册页面,打开激活工具,点击Generate生成Keygen,点击Copy,粘贴到navicat注册页面中!点击激活按图中步骤操作,即可激活成功
2021年03月08日
229 阅读
0 评论
6 点赞
2020-12-08
利用CSS3制作旋转3D立方体
利用CSS3制作旋转3D立方体
2020年12月08日
742 阅读
0 评论
3 点赞
1
2
3