界面效果

设置说明: 设置文件在软件目录下的 set.xml

  1.              cuuId 为当前选择的时间同步服务器ID 就是下面第几个item里的配置 (从零开始)

  2.   
          item 时间服务器列表项  
          name 时间服务器名称  
          ip   时间服务器地址 
          ip2  保留
  3.    后台服务时间同步方式 
              type 1 开机就同步 同步成功后停止服务 
                 2 开始服务后每隔STime分钟同步一次 
              STime   间隔的时间
  4.   日志记录方式
               level 2   记录程序运行生成的调试信息和错误信息
                   3    只记录程序运行产生的错误信息
                   4   不记录任何日志

**注 在界面上或者手动修改配置文件后要手动停止服务在启动服务

程序出来缘由: http://caipiao365.vip/article/12

程序源码: https://gitee.com/zuzong/Projects/tree/master/MyTime

程序下载: https://gitee.com/zuzong/Projects/raw/master/MyTime/exe/MyTime.zip

 缘由 

 家里有两台老电脑,有cmos电池没有电了,还有应该是BIOS出问题了.每次开机后时间恢复成了出厂时间.虽然不是什么大问题,但是也给使用时带来了很大的不方便.然后用win的时间同步服务一直更新不成功.折腾了好长时间(不知道为什么),估计是人长的丑的缘故吧^_^,有知道原因的麻烦告诉我.然后在网上找了一些时间同步的工具,发现不是有广告就是要手动去更新时间,然后就想这与其乱费长时间去试一个个的软件,还不如自己花点时间写一个. 就这样[时间同步小助手]就出来. 

事因

先不废话,来张让人看了就上火的图片.因为平时用浏览器用的多.所以开机就喜欢打开chrome.结果出现下面这张可恶的图片.

然后打开服务一看,Windows Time服务是自动启动的 而且正在运行中.就这样我打一下面这个界面.


选择里面的服务器 点立即更新 都没法更新. 在这里自己输入时间服务器,结果也报错.没办法就来野蛮一点的打开注册表转到[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\DateTime\Servers]手动加时间服务器.然后重启在看里面有了但是还是更新出错.然后左百毒右谷歌,从比必到yandex. 搜到了一些大同小异的文章.然后高高兴兴的去按搜到的资料上的去做,结果我这台电脑居然不按套路出牌.

运行 w32tm  unregister

给我的回复是 

发生下列错误: 拒绝访问。 (0x80070005)

运行 w32tm  /debug /enable /file:......

给我的回复是 

发生下列错误: 拒绝访问。 (0x80070005)

反正执行 不管如何执行 w32tm的相关命令就给那一直不变的 友好的提示:发生下列错误: 拒绝访问。 (0x80070005)

 

然后就想着不想在折腾你了.没有那么多时间来折腾.去网上找时间同步的软件.下个一来丢盘即用就可以了.然后把时间更新了一下.打开chrom来搜 windows时间同步工具. 一看结果好多呀.然后又开始一个一个try.try. 结果大部分软件功能不好用,甚至还用不了.但是广告特别多.而且还绑定了好多的垃圾软件和流氓软件.应正了 安装5分钟,清理两小时.结果一个非常适合晒太阳的下午白白乱费了.然后我那暴躁的脾气上来了.想想宁愿去通宵几个晚上也要自己做一个时间同步小工具来用.说干就卷起袖子开干.

分析

打开 bing   搜  rfc ntp  找到这份文档 https://tools.ietf.org/html/rfc958 

慢慢的啃完了他.定义了下面的通讯结构(主要看 Appendix A UDP Header Format )

struct NTPPacket
{
    union
    {
        struct _ControlWord
        {
            unsigned int uLI : 2;          // 00 = no leap, clock ok
            unsigned int uVersion : 3;     // version 3 or version 4
            unsigned int uMode : 3;        // 3 for client, 4 for server, etc.
            unsigned int uStratum : 8;     // 0 is unspecified, 1 for primary reference system,
            // 2 for next level, etc.
            int nPoll : 8;                 // seconds as the nearest power of 2
            int nPrecision : 8;            // seconds to the nearest power of 2
        };

        int nControlWord;                  // 4
    };

    int nRootDelay;                       // 4
    int nRootDispersion;                  // 4
    int nReferenceIdentifier;             // 4

    __int64 n64ReferenceTimestamp;        // 8
    __int64 n64OriginateTimestamp;        // 8
    __int64 n64ReceiveTimestamp;          // 8

    int nTransmitTimestampSeconds;       // 4
    int nTransmitTimestampFractions;     // 4
};

/*
主要字段的解释如下:

l              LI(Leap Indicator):长度为2比特,值为“11”时表示告警状态,时钟未被同步。为其他值时NTP本身不做处理。

l              VN(Version Number):长度为3比特,表示NTP的版本号,目前的最新版本为3。

l              Mode:长度为3比特,表示NTP的工作模式。不同的值所表示的含义分别是:0未定义、1表示主动对等体模式、2表示被动对等体模式、3表示客户模式、4表示服务器模式、5表示广播模式或组播模式、6表示此报文为NTP控制报文、7预留给内部使用。

l              Stratum:系统时钟的层数,取值范围为1~16,它定义了时钟的准确度。层数为1的时钟准确度最高,准确度从1到16依次递减,层数为16的时钟处于未同步状态,不能作为参考时钟。

l              Poll:轮询时间,即两个连续NTP报文之间的时间间隔。

l              Precision:系统时钟的精度。

l              Root Delay:本地到主参考时钟源的往返时间。

l              Root Dispersion:系统时钟相对于主参考时钟的最大误差。

l              Reference Identifier:参考时钟源的标识。

l              Reference Timestamp:系统时钟最后一次被设定或更新的时间。

l              Originate Timestamp:NTP请求报文离开发送端时发送端的本地时间。

l              Receive Timestamp:NTP请求报文到达接收端时接收端的本地时间。

l              Transmit Timestamp:应答报文离开应答者时应答者的本地时间。

l              Authenticator:验证信息。

*/

 

核心代码

UDP通信的代码如下:

#define JAN_1970        0x83aa7e80 /* 1900年~1970年之间的时间秒数 */

bool TimeSockService::GetNetTime(const string strIP,UINT64 &uRetTime)
{
    SOCKET SendSocket;  
    sockaddr_in RecvAddr;  
    uRetTime = 0;
    UString strError; 
    SendSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
    RecvAddr.sin_family = AF_INET;  
    RecvAddr.sin_port = htons(123);  
    HOSTENT* pHostent = gethostbyname(strIP.c_str());  
    if (pHostent != NULL)
    {  
        RecvAddr.sin_addr.s_addr = *(u_long *)pHostent->h_addr_list[0];;  
    }else 
    {
        strError.Format(L"error in gethostbyname: %d \r\n%s", WSAGetLastError(), sysErrorMsg().c_str());
        LOG_ERR(strError.GetData());
        if (_hWndGUI) SendMessage(_hWndGUI, WM_GET_NET_TIME_ERR, 0, LPARAM(strError.GetData()));

        return false;  
    }

 
    NTPPacket ntpSend = { 0 };
    ntpSend.nControlWord = 0x1B;  
    NTPPacket ntpRecv;

    int tv_out = 5000; 
    setsockopt(SendSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&tv_out, sizeof(tv_out));
    sendto(SendSocket, (char*)&ntpSend, sizeof(ntpSend), 0, (SOCKADDR *)&RecvAddr, sizeof(RecvAddr));  

    sockaddr fromAddr = { 0 };  
    int nRead = sizeof(fromAddr);  
    if (SOCKET_ERROR != recvfrom(SendSocket, (char*)&ntpRecv, sizeof(ntpRecv), 0, &fromAddr, &nRead))  
    { 
        uRetTime = ntohl(ntpRecv.nTransmitTimestampSeconds) - JAN_1970; 
    }else
    {  
        strError.Format(L"error in recvfrom: %d \r\n%s", WSAGetLastError(), sysErrorMsg().c_str());
        LOG_ERR(strError.GetData());
        if (_hWndGUI) SendMessage(_hWndGUI, WM_GET_NET_TIME_ERR, 0, LPARAM(strError.GetData()));
    }
    closesocket(SendSocket);
    return true;
}

结果

然后封装成win的服务程序.为了方便管理做了个界面.具体效果如下:

验证结果

设置成开机同步后运行后看的效果:

具体用法请点界面上的说明 按钮.欢迎使用找BUG.有什么问题欢迎在这里砸砖头^_^

程序下载地址: https://gitee.com/zuzong/Projects/raw/master/MyTime/exe/MyTime.zip

个人博客地址:http://caipiao365.vip/article/12

更多帮助: http://caipiao365.vip/article/MyTime

习惯了linux的命令 然后在win下时不时的 输上了ls   clear 结果返回错误。然后自己又不想安装一在对的其他的环境。然后记得win下有一条命令是 doskey。可以给现有的命令取个别名。这个的话就方便多了

写一个小脚本 如下 保存成 doskey.cmd

@echo off
@doskey clear=cls $*
@doskey top=tasklist $*
@doskey ls=dir $*
@doskey mv=move $*
@doskey cp=copy $*
@doskey cat=type $*
@doskey pwd=echo %cd%
@doskey grep=findstr $*
@doskey ifconfig=ipconfig $*

要是还有其他的命令可以自己加



然后打开注册表

找到 HKEY_CURRENT_USER\Software\Microsoft\Command Processor这里

在这里下面 建立一个 名叫 AutoRun的字符串 值为上面脚本保存的路径,如下图


保存后在打开cmd就可以看效果了



希望对大家有用



刚刚从服务器上备份了一下数据库然后要到本机调试一些东西,结果点导入时给我提示出错了.

然后二话不说去看了下文件编码, 一看是UTF-8的想应该是没有BOM的原因,然后二话不说打开notepad++ 给他加上BOM标示.


结果提示文件太大.在试了一下vscode也提示文件太大.然后就不想试期他的了.要想一下如何给这个大文件加上BOM标示呢. 脑壳疼脑壳疼.疼了一下就想灵光一现.


开始装B了.

  1. 打开notepad++(其他的编辑器也可以) 建立一下文本文件 输入 --(因为--是sql的注释字符) 然后保存成带BOM的文件 我给他取名为 bom.sql,如下图片

  2.  然后打开CMD执行下面的命令

    copy bom.sql+bak.sql  1.sql


在把1.sql导入到DB里面


装B成功



上面只供参考,要是个位还有其他的好方法麻烦告诉我^_^



摘要: 曾经在工作当时招的各种各样的程序员。也带过各种各样的人。然后在带人的过程中发现了一些短板,所以就准备写几片程序设计之学前班的基础文章来。暂时先上一篇看看效果。要是觉得好麻烦告诉你的身边的人或者好友。要是觉得不好麻烦您一定要告诉我。

前言

在我们的日常生活用语里经常用的就一个词就是半斤八两,首先我介绍一下半斤为什么是八两.在中国以前重量的单位的16进制的,就是16两等于一斤,当然在香港还是保持着司马量的习惯.(台湾没有去过不知道).后来建国后为了和国际接轨才改成了十两一斤.当然这里不是给大家普及一这个小知识.这里要注意的是  16两为一斤.就是缝16进一.也就是16进制.看看中国是最早使用16进制的国家吧.当然不单单是16进制.为会标题说堂堂5尺爷们不到100斤呢,这里不是在吸引眼球瞎说,尺是长度单位,1米大概是3.3333尺,算一下5尺就是1.666米左右,一个1.6米左右的爷们不到160斤那纯粹是个标准身材.要是超过了那么就是太有安全感了.

数字的进制

刚刚说了16进制是逢16进一的,还有逢二进一二进制, 逢8进一的8进制, 逢12进一的12进制如时间. 逢60进一时时间的分秒等,这些在我们生活当中经常使用的.而且用了好多好多年了.

二进制

如你家开饭的时候你要去摆碗筷.如人5个人你就要拿5双筷子,而不是说要10只筷子.看看我们的老祖宗是最早使用二进制的.而且把还做了几次运算先转换成二进制,在转换成十进制.

二进制数只有0和1两个基本数字,由于大家都知道直流电只有正负两个电极所以在电器设备里(我说的是数字电器设备) 容易在电气元件中实现,所以用二进制表示非常方便,

二进制数的运算

二进制数的运算公式:

0+0=0 0×0=0

0+1=1 0×1=0

1+0=1 1×0=0

1+1=10 1×1=1

八进制

八进制也是我们国家用的最早的.我一说大家就想到了是八卦,对就是八卦,但是八卦不单单是八进制,他是八进制和二进制结合的产物.在这里不去详细讲解.这个只做了解就可以了,具体原因后面在讲.

十六进制

这个刚刚在前言里讲了不在详细讲解了. 16进制要16个字符来表示.其中 0到9表前前10个字符, 然后用字符ABCEDF这几个字符来表示 11 12 13 14 15.在计算机为了表示数据就用了16进制,这个非常好理解.如你家要是有100个有吃饭,你要准备多少个碗,多少双筷子时不是说的是 100个碗 100双筷子了,大部分说的是 要准备13(我说的是八仙桌,就是八人一桌的)桌的餐具了.看看日常生活当中又用到了8进制和二进制,而且是个正常人就会听明白.为会要说13桌不说100个碗和100双(或200根)筷子呢.主要是方便自己说的文字少了.别人一听就明白.所以计算机为了显示一些数据用的是16进制的方式去显示.如果用二进制去显示那么显示的文字就非常多一大堆的0和1不方便.

不同进制的转换

接着上面的说100个人要准备13着的问题,在这个100人变13桌的过程中您已经把10进制转换成了8进制然后在转换成了10进制,几乎是不假思索的.但是计算机就比你笨了好几个次方倍了,应为他不会转换.他的转换是人告诉的.现在来看看外国的那些猴子是怎么教计算机来转换不同的进制的

1.  十进制和二进制间的转换

将十进制整数转换成二进制整数时,只要将它一次一次地被2除,得到的余数从最后一个余数读起)就是二进制表示的数。

2.   二进制数转换成十进制数

将一个二进制数的整数转换成十进制数,只要将按权展开。

例:11011=1*24(2的4次方)+1*23(2的3次方)+0*22(2的2次方)+1*21(2的1次方)+1*20(2的0次方)=27

3. 不同进制数的转换

二进制数和八进制数互换:二进制数转换成八进制数时,只要从小数点位置开始,向左或向右每三位二进制划分为一组(不足三位时可补0),然后写出每一组二进制数所对应的八进制数码即可。

例:将二进制数(10110001.111)转换成八进制数:

010 110 001. 111

2 6 1 7

即二进制数(10110001.111)转换成八进制数是(261.7)。反过来,将每位八进制数分别用三位二进制数表示,就可完成八进制数和二进制数的转换。

二进制数和十六进制数互换:二进制数转换成十六进制数时,只要从小数点位置开始,向左或向右每四位二进制划分为一组(不足四位时可补0),然后写出每一组二进制数所对应的十六进制数码即可。

例:将二进制数(11011100110.1101)转换成十六进制数:

0110 1110 0110. 1101

6 E 6 D

即二进制数(11011100110.1101)转换成十六进制数是(6E6.D)。反过来,将每位十六进制数分别用三位二进制数表示,就可完成十六进制数和二进制数的转换。

八进制数、十六进制数和十进制数的转换:这三者转换时,可把二进制数作为媒介,先把代转换的数转换成二进制数,然后将二进制数转换成要求转换的数制形式。

 

数据的编码----之MS的崛起

也许你听过MS,或者没有听过MS,但是或多或少你都用过MS的东西.如他的操作系统windows,他的办公软件 office他的浏览器IE等,但是你也许不知道MS这艘航母是怎么从当时的地下车库一步一步的搬进他现在的大厦的.

先我来啰嗦一下,说说前面的8进制,本来是我们的老祖宗玩的非常溜的,但是由于这个8进制在曾经很长的一段时间内制约了中国的计算机发展,乃至于全球的(个人是这样认为的).为什么呢?现在我来慢慢和你道来:

大家都知道,我们的电脑全的全称叫电子数字试计算机.看看电子数字试这几个子,电子我们初中的物理老师和化学老师讲了只有正极和负极.那么数字试是什么意思想,正极和负极可以表示多少个数字呢?好吧我也不知道,高中数学课上开小差了.那我们现在来一个非常完美的假设

有两个电极如下(用0表示- 用1表示+)

电极A

电极B

结果

0

0

第一种情况

0

1

第二种情况

1

0

第三种情况

1

1

第四种情况

聪明的您肯定一下就算出来了 2*2=4种情况了.是的没有错就是两个位可以表示的信息非常有限就只能表示4种信息.当然计算机是国外的科学家发明的.他们可能都不会中文,因为他们用的是英文说的是英语.我们看看因为是26个字母.包括大小些才52个 在加上一0到9十个常用的数字.才62个,想想还有一写标点符号,有多少个初中的英语老师没有告诉我,我就假设一下吧,算30个吧应该差不多了吧.这样的话62+30才90多个不到100个.数学好的你肯定就知道了,要多少个位就可以表示完这100来个的信息了.对7个位就可以表示完了.7位组合下来可以表示128个信息.但是中国有句老话叫孤阴不生,独阳不长.这话的什么意思呢.自己去google里百度.我只知道让你去提水,你肯定提2的倍数是最优的,因为不是二的倍数的话有一次是单的.电器设备里的电极也是成双成对出现的,计算机里的最基本的单位是bit(位),但是美国的那些科学家们只考虑了他的使用环境,就把计算机的的一个字节定义成了8个位.为什么是8个呢.因为表示他们的单词和数字以及标点符号等这些有7个位足够了.所以他们就定义出来了一个字节8个位.

1个字节=8个位

1k=1024个字节

1M=1024K

1G=1024M

1T=1024G

美国信息交换标准代码

据说long long a go. 电脑不像现在的这样(废话). 现在我可以在我电脑上编辑好一份文件然后发给你,你就可以在你的电脑上打开看了甚至编辑了.要是在很久以前的,那些用电脑的人看到了就会觉得非常非常神奇.应为以前的电脑在a电脑上编辑的文件只能在a电脑上看.不能在b电脑上看.两边电脑的系统信息编码不一样.然后MS就出来.比尔该死借助他妈是IBM销售部的部长.他就写了一套软件系统.基本上和当时市面上用的功能是一模一样的,但是他比其他的dos多了一个功能.就是在任何一台安装有MS_DOS的IBM兼容机上编辑的文件可以在其他任何一台安装MS_DOS的IBM兼容机上打开并且编辑.这样使得他的系统大买,也让IBM的PC机也大买.后来你懂得了,有钱,有个好妈妈.抱上了巨人(还是国际巨人)的大腿.很会做销售和市场(废话,当妈就是销售精英),还懂技术的人.想不挣钱都难.所以他就二话不说.从学校和老师说了句我妈妈叫我回家数钱去.就辍学了.

 

美国标准信息交换代码是由美国国家标准学会(American National Standard Institute , ANSI )制定的,标准的单字节字符编码方案,用于基于文本的数据。起始于50年代后期,在1967年定案。它最初是美国国家标准,供不同计算机在相互通信时用作共同遵守的西文字符编码标准,它已被国际标准化组织(International Organization for Standardization, ISO)定为国际标准,称为ISO 646标准。适用于所有拉丁文字字母。 

标准表

(图片来源百度百科)

 

 

 

汉字编码

在计算机中一个汉字通常用两个字节的编码表示,我国制定了“中华人民共和国国家标准信息交换汉字编码字符集(基本集GB2312—1980)”,简称国标码,是计算机进行汉字信息处理和汉字信息交换的标准编码。在该编码中,共收录汉字和图形符号7445个,其中一级常用汉字3755个(按汉语拼音字母顺序排列),二级常用汉字3008个(按部首顺序排列),图形符号682个。

在GB2312—1980中规定,全部国标汉字及符号组成一个94×94的矩阵。在此矩阵中,每一行称为一个“区”,每一列称为一个“位”。于是构成了一个有94个区(01~94区),每个区有94个位(01~94位)的汉字字符集。区码与位码组合在一起就形成了“区位码”,唯一地确定某一汉字或符号。

区位码的分布规则如下:

1)01~09区:图形符号区。

2)10~15区:自定义符号区。

3)16~55区:一级汉字区,按汉字拼音排序,同音字按笔画顺序。

4)56~87区:二级汉字区,按偏旁部首、笔画排序。

5)88~94区:自定义汉字区。

(2)汉字输入码

所谓汉字输入码就是用于使用西文键盘输入汉字的编码。每个汉字对应一组由键盘符号组成的编码,不同的汉字输入法其输入码不同。汉字输入码也称外码。常见的汉字输入编码方案可分为如下4类:

1)数码:用数字组成的等长编码,典型代表有区位码、电报码。

2)音码:根据汉字的读音组成的编码,典型代表有全拼码和双拼码。

3)形码:根据汉字的形状、结构特征组成的编码,典型代表有五笔字型、表形码。

4)音形码:将汉字读音与其结构特征综合考虑的编码,典型代表有自然码、首尾拼音码。

(3)汉字内码

无论用户用哪种输入法,汉字输入到计算机后都转换成汉字内码进行存储,以方便机内的汉字处理。汉字内码是采用双字节的变形国标码,在每个字节的低7位与国标码相同,每个字节的最高位为1,以与ASCII码字符编码区别。

(4)汉字字形码

汉字字形码(汉字输出码)是将点阵组成的汉字模型数字化,形成一串二进制数称为汉字字形码,其主要用于输出汉字。输出汉字时,将汉字字形码再还原为由点阵构成的汉字,所以汉字字形码又被称为汉字输出码。

汉字是一种象形文字,每一个汉字可以看成是一个特定的图形,这种图形可以用点阵、 轮廓向量、骨架向量等多种方法表示,而最基本的是用点阵表示。如果用16x16点阵来表示 一个汉字,则一个汉字占16行,每一行有16个点,其中每一个点用一个二进制位表示,值“0” 表示暗,值“1”表示亮。由于计算机存储器的每个字节有8个二进制位,因此,16个点要用 两个字节来存放,16x16点阵的一个汉字字形需要用32个字节来存放,这32个字节中的信息 就构成了一个16x16点阵汉字的字模

Unicode

Unicode(统一码、万国码、单一码)是计算机科学领域里的一项业界标准,包括字符集、编码方案等。Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。1990年开始研发,1994年正式公布。

 




注意:本文属于原创。首发于自己的博客: http://caipiao365.vip/article/25

欢迎转载,转载请保留上面的链接谢谢合作。版权保留。