從網(wǎng)上下載的網(wǎng)站源碼怎么用免費(fèi)企業(yè)建站
完整源碼,附工程下載,工程其實(shí)也就下面兩個(gè)代碼。
想在不能上網(wǎng)的服務(wù)器局域網(wǎng)中部署一個(gè)時(shí)間服務(wù)NTP,當(dāng)然系統(tǒng)自帶該服務(wù),可以開(kāi)啟,本文只是分享一下該協(xié)議報(bào)文和能跑的源碼。網(wǎng)上作為服務(wù)的源碼不太常見(jiàn),能見(jiàn)到不一定能跑起來(lái),缺胳膊少腳的,分享代碼一定要分享全。
先來(lái)效果圖:
開(kāi)啟程序后,讓win系統(tǒng)來(lái)同步本機(jī)時(shí)間效果如下:
用通用客戶端GuerrillaNtp來(lái)讀,也沒(méi)有問(wèn)題:
添加圖片注釋,不超過(guò) 140 字(可選)
Fuck Shut Up,Show me the code
源碼如下:
運(yùn)行入口:
namespace NTP
{internal class Program{static void Main(string[] args){Console.WriteLine("Hello, NTP(SNTP)!");Console.WriteLine("本程序占用 UDP 123 端口,如遇沖突,請(qǐng)關(guān)閉系統(tǒng)自帶時(shí)間服務(wù) W32Time(Windows Time)");new SNTPServer().Start();Console.ReadLine();}}
}
主程序代碼:
using System.Net.Sockets;
using System.Net;
using System.Buffers.Binary;namespace NTP
{/// <summary>/// 簡(jiǎn)單網(wǎng)絡(luò)時(shí)間協(xié)議服務(wù)器/// </summary>public class SNTPServer{int port = 123; //服務(wù)端口,NTP默認(rèn)端口123bool stopFlag = false; //通知后臺(tái)線程停止消息循環(huán)的標(biāo)識(shí)Thread tdServer; //服務(wù)器后臺(tái)監(jiān)聽(tīng)線程/// <summary>/// 初始化一個(gè)簡(jiǎn)單網(wǎng)絡(luò)時(shí)間協(xié)議服務(wù)器/// </summary>public SNTPServer(): this(123) { }/// <summary>/// 使用指定參數(shù)初始化一個(gè)簡(jiǎn)單網(wǎng)絡(luò)時(shí)間協(xié)議服務(wù)器/// </summary>/// <param name="port">服務(wù)端口</param>public SNTPServer(int port){this.port = port;}/// <summary>/// 獲取和設(shè)置服務(wù)端口號(hào)/// </summary>public int Port{get { return this.port; }set { this.port = value; }}/// <summary>/// 啟動(dòng)服務(wù)器/// </summary>public void Start(){if (tdServer == null || (!tdServer.IsAlive)){tdServer = new Thread(bgWork);tdServer.IsBackground = true;stopFlag = false;tdServer.Start();}}/// <summary>/// 停止服務(wù)器/// </summary>public void Stop(){stopFlag = true;}private void bgWork(){IPEndPoint iep;UdpClient udpclient;try{iep = new IPEndPoint(IPAddress.Any, port);udpclient = new UdpClient(iep);while (!stopFlag){if (udpclient.Available > 0){Console.WriteLine("收到一個(gè)請(qǐng)求:" + iep.Address + " 端口:" + iep.Port);byte[] buffer;IPEndPoint remoteipEP = new IPEndPoint(IPAddress.Any, port);buffer = udpclient.Receive(ref remoteipEP);if (buffer.Length >= 48){var bytesReceive = buffer.AsSpan();Console.WriteLine("收到數(shù)據(jù)[" + buffer.Length + "]:" + BitConverter.ToString(buffer));//記錄收到請(qǐng)求的時(shí)間DateTime ReceiveTimestamp = DateTime.Now;//對(duì)方請(qǐng)求發(fā)出的時(shí)間,拿來(lái)顯示看看DateTime? OriginateTimestamp = Decode(BinaryPrimitives.ReadInt64BigEndian(bytesReceive[40..]));//傳輸?shù)亩际菄?guó)際時(shí)間,這里顯示方便轉(zhuǎn)成北京時(shí)間Console.WriteLine("對(duì)方請(qǐng)求發(fā)出時(shí)間:" + OriginateTimestamp?.ToLocalTime().ToString("yyyy-MM-dd HH:mm:ss.fff"));var Mode = 4;var VersionNumber = 3;var LeapIndicator = 0;var Stratum = 4;//Stratum 0是最高層級(jí),代表原子鐘、GPS接收器或其他高精度的時(shí)間源。var Poll = 0x0A;//NTP客戶端向遠(yuǎn)程服務(wù)器發(fā)送時(shí)間請(qǐng)求的間隔(以秒為單位)。var Precision = 0xE9;buffer = new byte[48];var bytes = buffer.AsSpan();//LI(Leap Indicator):長(zhǎng)度為2比特,值為“11”時(shí)表示告警狀態(tài),時(shí)鐘未被同步。為其他值時(shí)NTP本身不做處理。//VN(Version Number):長(zhǎng)度為3比特,表示NTP的版本號(hào),目前的最新版本為3。//Mode:長(zhǎng)度為3比特,表示NTP的工作模式。不同的值所表示的含義分別是:0未定義、1表示主動(dòng)對(duì)等體模式、2表示被動(dòng)對(duì)等體模式、3表示客戶模式、4表示服務(wù)器模式、5表示廣播模式或組播模式、6表示此報(bào)文為NTP控制報(bào)文、7預(yù)留給內(nèi)部使用。//0x1C = 00 011 100bytes[0] = (byte)(((uint)LeapIndicator << 6) | ((uint)VersionNumber << 3) | (uint)Mode);bytes[1] = (byte)Stratum;bytes[2] = (byte)Poll;bytes[3] = (byte)Precision;BinaryPrimitives.WriteInt32BigEndian(bytes[4..], Encode(TimeSpan.Zero));//RootDelay = 0; Root Delay?是指從主參考時(shí)鐘到NTP服務(wù)器之間的往返時(shí)間延遲。它表示從主參考時(shí)鐘到NTP服務(wù)器再返回的總體時(shí)間,通常以毫秒為單位。BinaryPrimitives.WriteInt32BigEndian(bytes[8..], Encode(TimeSpan.Zero));//RootDispersion = 0; Root Dispersion?是指本地時(shí)鐘相對(duì)于主參考時(shí)鐘的最大誤差。它表示NTP服務(wù)器時(shí)鐘與主參考時(shí)鐘之間的最大時(shí)間偏差,通常以毫秒為單位。BinaryPrimitives.WriteUInt32BigEndian(bytes[12..], BitConverter.ToUInt32(new byte[] { 0x41, 0x43, 0x54, 0x53 }, 0));//ReferenceIdentifierBinaryPrimitives.WriteInt64BigEndian(bytes[16..], Encode(DateTime.Now.ToUniversalTime()));//ReferenceTimestamp 系統(tǒng)時(shí)鐘最后一次被設(shè)定或更新的時(shí)間//對(duì)方請(qǐng)求發(fā)出的時(shí)間 轉(zhuǎn)成datetime 再轉(zhuǎn)字節(jié) 會(huì)造成精度損失,【請(qǐng)求端會(huì)不認(rèn)該報(bào)文】,應(yīng)該返回原裝字節(jié), //BinaryPrimitives.WriteInt64BigEndian(bytes[24..], Encode(OriginateTimestamp));bytes[24] = bytesReceive[40];bytes[25] = bytesReceive[41];bytes[26] = bytesReceive[42];bytes[27] = bytesReceive[43];bytes[28] = bytesReceive[44];bytes[29] = bytesReceive[45];bytes[30] = bytesReceive[46];bytes[31] = bytesReceive[47];BinaryPrimitives.WriteInt64BigEndian(bytes[32..], Encode(ReceiveTimestamp.ToUniversalTime()));//ReceiveTimestampBinaryPrimitives.WriteInt64BigEndian(bytes[40..], Encode(DateTime.Now.ToUniversalTime()));//TransmitTimestampConsole.WriteLine("返回?cái)?shù)據(jù)[" + buffer.Length + "]:" + BitConverter.ToString(buffer));//系統(tǒng)NTP真實(shí)返回報(bào)文示例//buffer = new byte[] { 0x1C,0x04,0x00,0xE9,0x00,0x00,0x21,0xAA,0x00,0x00,0x16,0x0C,0x34,0xE7,0x72,0xB7,0xEB,0x0E, 0x62, 0x72,0xF7,0xCF,0x33,0xAF,0xEB,0x0E, 0x66, 0x3E, 0x79, 0x8B,0xB0,0x00,0xEB,0x0E, 0x66, 0x3E, 0x97, 0xCE,0xE6,0x82,0xEB,0x0E, 0x66, 0x3E, 0x97, 0xCF,0x51,0xE2 };udpclient.Send(buffer, buffer.Length, remoteipEP);}}}}catch (Exception e){Console.WriteLine(e.ToString());}}private const double FACTOR = 1L << 32;static readonly DateTime epoch = new DateTime(1900, 1, 1, 0, 0, 0, DateTimeKind.Utc) + TimeSpan.FromSeconds(1L << 32);static int Encode(TimeSpan time) => (int)(time.TotalSeconds * (1 << 16));static long Encode(DateTime? time) => time == null ? 0 : Convert.ToInt64((time.Value - epoch).TotalSeconds * (1L << 32));static DateTime? Decode(long bits) => bits == 0 ? null : epoch + TimeSpan.FromSeconds(bits / FACTOR);}
}
本代碼親自測(cè)試,木有問(wèn)題.
工程下載:download.csdn.net/download/wudizhukk/90159750