开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 695|回复: 13
收起左侧

[易语言纯源码] NTP同步互联网时间,大模型测试翻译易代码,无痛迁移到C

[复制链接]
结帖率:100% (1/1)
发表于 2024-8-15 22:07:28 | 显示全部楼层 |阅读模式   江苏省南通市
分享源码
界面截图:
是否带模块: 纯源码
备注说明: -
本帖最后由 猫神父 于 2024-8-15 22:23 编辑

同样的代码,易语言编译后有点大104k,代码也有点长
迁移成C之后编译只有15.5k

  
窗口程序集名保 留  保 留备 注
程序集1   
子程序名返回值类型公开备 注
_启动子程序整数型 请在本子程序中放置动态链接库初始化代码
_临时子程序 ()  ' 在初始化代码执行完毕后调用测试代码
返回 (0)  ' 返回值被忽略。
子程序名返回值类型公开备 注
_临时子程序  
变量名类 型静态数组备 注
time长整数型 
' 本名称子程序用作测试程序用,仅在开发及调试环境中有效,编译发布程序前将被系统自动清空,请将所有用作测试的临时代码放在本子程序中。 ***注意不要修改本子程序的名称、参数及返回值类型。
time = GetNTPTime ()
' 到时间 (取字节集数据 (到字节集 (time), #日期时间型, ))
输出调试文本 (强制类型转换 (time, #日期时间型 ))
子程序名返回值类型公开备 注
GetNTPTime长整数型 
变量名类 型静态数组备 注
time长整数型 
计次循环首 (5, )
time = NTP时间 (NTP服务器池 (), 500)
如果真 (time ≠ 0)
跳出循环 ()

计次循环尾 ()
返回 (time)
子程序名返回值类型公开备 注
NTP服务器池文本型 
变量名类 型静态数组备 注
TimeURL文本型0
n整数型 
TimeURL = 分割文本 ( #NTP_SERVER, #换行符, )
变量循环首 (取数组成员数 (TimeURL), 1, -1, n)
如果真 (TimeURL [n]“”)
删除成员 (TimeURL, n, )

变量循环尾 ()
置随机数种子 (取启动时间 ())
n = 取随机数 (1, 取数组成员数 (TimeURL))
输出调试文本 (“NTP:” + TimeURL [n])
返回 (TimeURL [n])
子程序名返回值类型公开备 注
NTP时间长整数型 
参数名类 型参考可空数组备 注
NTP_URL文本型
timeout整数型
变量名类 型静态数组备 注
NTP_PORT整数型 
数据包字节集 
hSocket  
hConnect  
iResult  
补偿值  
时标长整数型4
时间数据字节集 
正确时间日期时间型 
NULL长整数型 
T字节集3
Buffer整数型 
ret整数型 
NTP_PORT = 123
如果真 (套接字_加载服务 ())
hSocket = 套接字_创建 ()
如果真 (hSocket ≠ 0)
如果真 (套接字_置超时 (hSocket, timeout))
hConnect = 套接字_连接 (hSocket, NTP_URL, NTP_PORT)
如果真 (hConnect ≠ -1)
时标 [1]取时间标识 ()
数据包 = { 27 }取重复字节集 (39, { 0 })到字节集 (时标 [1])  ' 48个字节' 取时间间隔 (取现行时间 (), [1970年1月1日], #秒)  ' 也可以—>取时间标识 ()  ' 始发时间戳
如果真 (套接字_发送 (hSocket, 数据包))
时标 [4]取时间标识 ()
Buffer = _申请内存 (48)
ret = Recv (hSocket, Buffer, 48, 0)
如果真 (ret ≠ -1)
时间数据 = 指针到字节集 (Buffer, 48)
T [1]取字节集中间 (时间数据, 25, 8)
T [2]取字节集中间 (时间数据, 33, 4)
T [3]取字节集中间 (时间数据, 41, 4)
时标 [2]转换字节序 (T [2])
时标 [3]转换字节序 (T [3])
补偿值 (时标 [2] - 时标 [1] + 时标 [3] - 时标 [4]) ÷ 2
如果真 (T [1]到字节集 (时标 [1]))
正确时间 = 增减时间 (取现行时间 (), #秒, 补偿值)
_释放内存 (Buffer)
套接字_销毁 (hConnect)
套接字_销毁 (hSocket)
套接字_卸载服务 ()
返回 (取字节集数据 (到字节集 (正确时间), #长整数型, ))


_释放内存 (Buffer)

' 4层对应连接
套接字_销毁 (hConnect)


' 2层对应套接字创建
套接字_销毁 (hSocket)

' 1层对应加载
套接字_卸载服务 ()
返回 (NULL)
子程序名返回值类型公开备 注
转换字节序长整数型 
参数名类 型参考可空数组备 注
时标字节组字节集
返回 (到数值 (时标字节组 [1]) × 16777216 + 到数值 (时标字节组 [2]) × 65536 + 到数值 (时标字节组 [3]) × 256 + 到数值 (时标字节组 [4]))
子程序名返回值类型公开备 注
取时间标识长整数型 
变量名类 型静态数组备 注
时标长整数型 
时标 = 取时间间隔 (取现行时间 (), [1900年1月1日], #秒 ) + 4294967296  ' ' ----因计算果已经溢出。故用+4294967296求补(2^32次方)获得正确结果
返回 (时标 - 28800)  ' - 28800 修正8小时时区差。 3600*8=60*60*8
子程序名返回值类型公开备 注
域名转IP长整数型 根据指定的机器名取IP地址。失败返回空。本命令为超级命令。
参数名类 型参考可空数组备 注
域名文本型要取得IP地址的机器名。
变量名类 型静态数组备 注
lpHost整数型 
HOSTHOSTENT 
dwIPAddr整数型 
tmpIPAddr字节型0
i整数型 
IP地址文本型 
lpHost = GetHostByName (到文本 (域名))
如果真 (lpHost = 0)
WSACleanup ()
返回 (0)
RtlMoveMemoryAny (HOST, lpHost, 16)
RtlMoveMemoryGetInt (dwIPAddr, HOST.hAddrList, 4)
重定义数组 (tmpIPAddr, 假, HOST.hLen)
RtlMoveMemoryBit (tmpIPAddr, dwIPAddr, HOST.hLen)
计次循环首 (HOST.hLen, i)
如果 (i = HOST.hLen)
IP地址 = IP地址 + 到文本 (tmpIPAddr [i])
IP地址 = IP地址 + 到文本 (tmpIPAddr [i])“.”

计次循环尾 ()
返回 (Inet_Addr (IP地址))
子程序名返回值类型公开备 注
强制类型转换通用型 
参数名类 型参考可空数组备 注
变量通用型
类型整数型常量 #整数型 #日期时间型 等等
置入代码 ({ 139, 69, 8 })
' mov eax,[ebp+08h]
判断 (类型 = #字节型 )
置入代码 ({ 185, 1, 1, 0, 128 })
' 可容纳 0 到 255 之间的数值。
' mov ecx,80000101h
判断 (类型 = #短整数型 )
' 可容纳 -32,768 到 32,767 之间的数值, 尺寸为 2 个字节。
置入代码 ({ 185, 1, 2, 0, 128 })
' mov ecx,80000201h
判断 (类型 = #整数型 )
' 可容纳 -2,147,483,648 到 2,147,483,647 之间的数值, 尺寸为 4 个字节。
置入代码 ({ 185, 1, 3, 0, 128 })
' mov ecx,80000301h
判断 (类型 = #长整数型 )
' 可容纳 -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 之间的数值, 尺寸为 8 个字节。
置入代码 ({ 139, 80, 4 })
' mov edx,[eax+4]
置入代码 ({ 185, 1, 4, 0, 128 })
' mov ecx,80000401h
判断 (类型 = #小数型 )
' 可容纳 3.4E +/- 38 (7位小数) 之间的数值, 尺寸为 4 个字节。
置入代码 ({ 185, 1, 5, 0, 128 })
' mov ecx,80000501h
判断 (类型 = #双精度小数型 )
' 可容纳 1.7E +/- 308 (15位小数) 之间的数值, 尺寸为 8 个字节。
置入代码 ({ 139, 80, 4 })
' mov edx,[eax+4]
置入代码 ({ 185, 1, 6, 0, 128 })
' mov ecx,80000601h
判断 (类型 = #逻辑型 )
' 值只可能为“真”或“假”,尺寸为 2 个字节。
置入代码 ({ 185, 2, 0, 0, 128 })
' mov ecx,80000002h
判断 (类型 = #日期时间型 )
' 用作记录日期及时间, 尺寸为 8 个字节。
置入代码 ({ 139, 80, 4 })
' mov edx,[eax+4]
置入代码 ({ 185, 3, 0, 0, 128 })
' mov ecx,80000003h
判断 (类型 = #文本型 )
' 用作记录一段文本, 文本由以字节 0 结束的一系列字符组成。
置入代码 ({ 185, 4, 0, 0, 128 })
' mov ecx,80000004h
判断 (类型 = #字节集型 )
' 用作记录一段字节型数据。字节集与字节数组之间可以互相转换, 两者之间唯一的不同是字节集可以变长, 因此可把字节集看作可变长的字节数组。
置入代码 ({ 185, 5, 0, 0, 128 })
' mov ecx,80000005h
' 置入代码 ({ 185, 5, 0, 0, 128 })
判断 (类型 = #子程序指针型 )
' 作指向一个子程序, 尺寸为 4 个字节。
置入代码 ({ 185, 6, 0, 0, 128 })
' mov ecx,80000006h


置入代码 ({ 139, 0, 201, 194, 8, 0 })
' mov eax,[eax]
' leave
' retn 8
返回 (0)


用大模型迁移成C,用中文宏定义C的变量名和函数名,代码如下(该代码可以直接编译成x86、x64程序):
  
#define _CRT_SECURE_NO_WARNINGS
#define 格式化打印 _snprintf
#include
#include
#include
#include
#include
#include
#include
#include
#pragma comment (lib, "ws2_32.lib")
#define NTP时间戳差值 2208988800ull
#define 最大服务器数 20
#define _CRT_SECURE_NO_WARNINGS
#define 无符号字节 uint8_t
#define 无符号整型 uint32_t
#define 长整数型 long long
#define 时间类型 time_t
#define 字节型 char
#define 双精度小数型 double
#define 整数型 DWORD
#define 短整数型 short
typedef struct {
无符号字节 li_vn_模式;
无符号字节 层级;
无符号字节 轮询;
无符号字节 精度;
无符号整型 根延迟;
无符号整型 根离散;
无符号整型 参考标识;
无符号整型 参考时间_秒;
无符号整型 参考时间_分数;
无符号整型 原始时间_秒;
无符号整型 原始时间_分数;
无符号整型 接收时间_秒;
无符号整型 接收时间_分数;
无符号整型 发送时间_秒;
无符号整型 发送时间_分数;
} NTP数据包;
typedef struct {
字节型 地址[256];
int 失败次数;
} NTP服务器;
NTP服务器 ntp服务器列表[最大服务器数] = {
{ "ntp.aliyun.com", 0 },
{ "time.asia.apple.com", 0 },
{ "cn.ntp.org.cn", 0 },
{ "time.windows.com", 0 },
{ "cn.pool.ntp.org", 0 },
{ "asia.pool.ntp.org", 0 },
{ "time.google.com", 0 },
{ "time.cloudflare.com", 0 },
{ "time.hko.hk", 0 },
{ "ntp.nict.jp", 0 },
{ "time.nist.gov", 0 },
{ "ntp.tuna.tsinghua.edu.cn", 0 },
{ "ntp.neu.edu.cn", 0 },
{ "ntp.nc.u-tokyo.ac.jp", 0 },
{ "ntp.ix.ru", 0 }
};
int ntp服务器数量 = 15;
void 记录错误 (const 字节型* 服务器) {
FILE* 日志文件;
if (fopen_s (&日志文件, "error.log", "a") == 0 && 日志文件) {
fprintf (日志文件, "%s - 连接超时: %s\n", __DATE__, 服务器);
fclose (日志文件);
}
}
void 读取错误日志 () {
FILE* 文件;
if (fopen_s (&文件, "error.log", "r") == 0 && 文件) {
字节型 行[256];
while (fgets (行, sizeof (), 文件)) {
字节型* 服务器 = strstr (行, "连接超时: ");
if (服务器) {
服务器 += 20;
字节型* 结束 = strchr (服务器, ' \n');
if (结束) *结束 = ' \0';
for (int i = 0; i < ntp服务器数量; i++) {
if (strcmp (ntp服务器列表[i].地址, 服务器) == 0) {
memmove (&ntp服务器列表[i], &ntp服务器列表[i + 1], (ntp服务器数量 - i - 1) * sizeof (NTP服务器));
ntp服务器数量--;
break;
}
}
}
}
fclose (文件);
}
}
int 选择服务器 () {
int 总权重 = 0;
for (int i = 0; i < ntp服务器数量; i++) {
总权重 += (10 - ntp服务器列表[i].失败次数);
}
int 随机权重 = rand () % 总权重;
for (int i = 0; i < ntp服务器数量; i++) {
随机权重 -= (10 - ntp服务器列表[i].失败次数);
if (随机权重 < 0) {
return i;
}
}
return 0;
}
长整数型 获取NTP时间 () {
static int 已初始化 = 0;
if (!已初始化) {
读取错误日志 ();
已初始化 = 1;
}
WSADATA wsa数据;
if (WSAStartup (MAKEWORD (2, 2), &wsa数据) != 0) {
return 0;
}
srand ( (unsigned int)time (NULL));
LARGE_INTEGER 频率, 开始, 结束;
QueryPerformanceFrequency (&频率);
for (int 尝试 = 0; 尝试 < 5; 尝试++) {
int 服务器索引 = 选择服务器 ();
const 字节型* 主机名 = ntp服务器列表[服务器索引].地址;
短整数型 端口号 = 123;
字节型 端口字符串[6];
格式化打印 (端口字符串, sizeof (端口字符串), "%d", 端口号);
struct addrinfo 提示 = { 0 }, *服务器信息, *p;
提示.ai_family = AF_UNSPEC;
提示.ai_socktype = SOCK_DGRAM;
提示.ai_protocol = IPPROTO_UDP;
if (getaddrinfo (主机名, 端口字符串, &提示, &服务器信息) != 0) {
continue;
}
SOCKET 套接字 = INVALID_SOCKET;
for (p = 服务器信息; p != NULL; p = p->ai_next) {
套接字 = socket (p->ai_family, p->ai_socktype, p->ai_protocol);
if (套接字 == INVALID_SOCKET) {
continue;
}
整数型 超时 = 2000;
setsockopt (套接字, SOL_SOCKET, SO_RCVTIMEO, (const 字节型*)&超时, sizeof (超时));
setsockopt (套接字, SOL_SOCKET, SO_SNDTIMEO, (const 字节型*)&超时, sizeof (超时));
if (connect (套接字, p->ai_addr, (int)p->ai_addrlen) == SOCKET_ERROR) {
if (WSAGetLastError () == WSAETIMEDOUT) {
记录错误 (主机名);
ntp服务器列表[服务器索引].失败次数++;
}
closesocket (套接字);
套接字 = INVALID_SOCKET;
continue;
}
break;
}
if (套接字 == INVALID_SOCKET) {
freeaddrinfo (服务器信息);
continue;
}
QueryPerformanceCounter (&开始);
NTP数据包 数据包 = { 0 };
数据包.li_vn_模式 = 0x1b;
if (send (套接字, (字节型*)&数据包, sizeof (NTP数据包), 0) == SOCKET_ERROR) {
closesocket (套接字);
freeaddrinfo (服务器信息);
continue;
}
if (recv (套接字, (字节型*)&数据包, sizeof (NTP数据包), 0) == SOCKET_ERROR) {
if (WSAGetLastError () == WSAETIMEDOUT) {
记录错误 (主机名);
ntp服务器列表[服务器索引].失败次数++;
}
closesocket (套接字);
freeaddrinfo (服务器信息);
continue;
}
QueryPerformanceCounter (&结束);
数据包.发送时间_秒 = ntohl (数据包.发送时间_秒);
数据包.发送时间_分数 = ntohl (数据包.发送时间_分数);
时间类型 发送时间 = (时间类型) (数据包.发送时间_秒 - NTP时间戳差值);
双精度小数型 经过时间 = (结束.QuadPart - 开始.QuadPart) * 1000.0 / 频率.QuadPart;
时间类型 调整后时间 = 发送时间 + (时间类型) (经过时间 / 2000.0);
SYSTEMTIME 系统时间;
GetSystemTime (&系统时间);
FILETIME 文件时间;
SystemTimeToFileTime (&系统时间, &文件时间);
ULARGE_INTEGER 大整数;
大整数.LowPart = 文件时间.dwLowDateTime;
大整数.HighPart = 文件时间.dwHighDateTime;
大整数.QuadPart += (调整后时间 - time (NULL)) * 10000000ULL;
文件时间.dwLowDateTime = 大整数.LowPart;
文件时间.dwHighDateTime = 大整数.HighPart;
FileTimeToSystemTime (&文件时间, &系统时间);
SetSystemTime (&系统时间);
closesocket (套接字);
freeaddrinfo (服务器信息);
WSACleanup ();
return (长整数型)调整后时间;
}
WSACleanup ();
return 0;
}
int main () {
长整数型 ntp时间 = 获取NTP时间 ();
if (ntp时间 != 0) {
printf ("NTP时间已同步到系统\n");
时间类型 t = (时间类型)ntp时间;
struct tm 时间信息;
localtime_s (&时间信息, &t);
字节型 日期时间[64];
strftime (日期时间, sizeof (日期时间), "%Y-%m-%d %H:%M:%S", &时间信息);
printf ("同步后的系统时间: %s\n", 日期时间);
}
else {
printf ("获取NTP时间失败\n");
}
return 0;
}



C编译

C编译


黑月编译

黑月编译

NTP.e

20.86 KB, 下载次数: 19, 下载积分: 精币 -2 枚

ntp.7z

2.25 KB, 下载次数: 6, 下载积分: 精币 -2 枚

NTP中文化后的C代码

评分

参与人数 1精币 +1 收起 理由
kyo9766 + 1 感谢分享,很给力!~

查看全部评分


本帖被以下淘专辑推荐:

结帖率:100% (1/1)

签到天数: 1 天

 楼主| 发表于 2024-8-22 01:10:55 | 显示全部楼层   江苏省南通市
NTP同步网络时间C编译.7z (4.52 KB, 下载次数: 1)
回复 支持 反对

使用道具 举报

签到天数: 19 天

发表于 2024-9-1 14:33:44 | 显示全部楼层   陕西省西安市
用的是哪个大模型

点评

deepseek   江苏省南通市  发表于 2024-9-1 17:37
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)

签到天数: 11 天

发表于 2024-8-20 09:53:37 | 显示全部楼层   广东省汕头市
感谢大神分享~!
回复 支持 反对

使用道具 举报

签到天数: 19 天

发表于 2024-8-19 11:54:14 | 显示全部楼层   湖北省武汉市
感谢分享
回复 支持 反对

使用道具 举报

结帖率:100% (3/3)

签到天数: 17 天

发表于 2024-8-18 10:20:45 | 显示全部楼层   浙江省台州市
谢谢分享 支持
回复 支持 反对

使用道具 举报

结帖率:73% (8/11)

签到天数: 21 天

发表于 2024-8-18 00:40:07 | 显示全部楼层   河南省焦作市

支持开源~!感谢分享
回复 支持 反对

使用道具 举报

签到天数: 15 天

发表于 2024-8-17 19:46:48 | 显示全部楼层   江西省上饶市
感谢分享
回复 支持 反对

使用道具 举报

结帖率:80% (57/71)

签到天数: 21 天

发表于 2024-8-17 08:50:50 | 显示全部楼层   广东省深圳市
回复 支持 反对

使用道具 举报

结帖率:0% (0/1)

签到天数: 21 天

发表于 2024-8-17 06:00:25 | 显示全部楼层   江西省上饶市
网络时间同步,很实用啊。前两天就遇上主板电池没电,又不想换电池的主。哈哈。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 793400750,邮箱:wp@125.la
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表