如果真的要说底层的方法,那就是纯粹TCP/IP协议的实现了,发送一个含Timestamp的数据包过去,对方会返回一个包含Timestamp的数据包,分析数据包即可得到对方的时间。粗略可以查看这里:
http://www.cnpaf.net/class/tcpandip/05329185327162.html
很抓狂?的确,这些底层的事都比较痛苦……使用winsock API吧,那样会简单那么一点点……
例如如:
FC 41 A7 45 1D BA 06 00 3E 00 00 00 3E 00 00 00
即
01/12/2007 16:08:28
(01/12/2007 16:08:28顺序已经调整了,这样更适合人类看……) http://www.autoitx.com/forum.php?mod=viewthread&tid=338&extra=page%3D1
这篇有个连接的例子,可是提示出错.
Dim $computer ="pc"
Dim $Remoteuser ="admin"
Dim $Remotepass = "sanhen"
$objWMIService=$objlocator.connectserver($computer,"root/cimv2",$Remoteuser,$Remotepass)
$objlocator.connectserver 这个,提示:variable used without being declared.
我有$computer ="pc"的administrators用户名和密码, asdf 哥哥,表要这样说嘛..
俺是菜菜,向您学习,期待您给个api的例子...
回复 18# asdf 的帖子
这样需要一定的TCP/IP基础了。。。最简单的如果不用NET TIME的话,是用C/S结构了。这样客户端发包过来,服务发回一个包给客户端。。。直接对着帮助都可以画出来了。 求教,
c/s结构,有顾虑,如果s开着,有N>300个c端去连接的话,这样的s.......
还望各位大大们,能给wmi或者api的例子,或者s端 原帖由 木纳 于 2008-5-16 12:32 发表 http://www.autoitx.com/images/common/back.gif
求教,
c/s结构,有顾虑,如果s开着,有N>300个c端去连接的话,这样的s.......
还望各位大大们,能给wmi或者api的例子,或者s端
同步时间只是开机的时候同步, 我想应该不可能会300一起开机去同步吧! 就算300台一起同步也不会对服务端有太大影响的 又不是一直不停同步 以前也做过这方面的实验,发代码上来大家研究一下,代码是修改的 titer 兄弟发的 局域网内客户端自动连接服务端所以客户机不需要指定服务器IP地址 http://www.autoitx.com/forum.php?mod=viewthread&tid=811&extra=page%3D2
服务器代码:
UDPStartup()
$socket = UDPBind(@IPAddress1, 8410)
If @error <> 0 Then Exit
While 1
$data = UDPRecv($socket, 50)
If $data <> "" Then
If StringInStr($data,"client:") Then
$ip=StringSplit($data,":")
$socket1=UDPOpen($ip,8411)
$send=UDPSend($socket1,@HOUR & "," & @MIN & "," & @SEC & "," & @YEAR & "," & @MON & "," & @MDAY)
Sleep(100)
UDPCloseSocket($socket1)
EndIf
EndIf
sleep(10)
WEnd
Func OnAutoItExit()
UDPCloseSocket($socket)
UDPShutdown()
EndFunc
客户机代码:
$objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled != 0", "WQL", 0x10 + 0x20)
If IsObj($colItems) then
For $objItem In $colItems
Dim $netmask=""
$localIP=$objItem.IPAddress(0)
$ip=StringSplit($localIP,".")
$net=StringSplit($objItem.IPSubnet(0),".")
For $i=1 To $ip
If $i = $ip Then
$netmask=$netmask&BitOR($ip[$i],BitXOR($net[$i],255))
Else
$netmask=$netmask&BitOR($ip[$i],BitXOR($net[$i],255))&"."
EndIf
Next
If Ping($netmask,10) Then
UDPStartup()
$socket = UDPOpen($netmask, 8410)
$socket1 = UDPBind($localIP,8411)
$status = UDPSend($socket, "client:"&$localIP )
If $status <> 0 then
UDPCloseSocket($socket)
While 1
$data = UDPRecv($socket1, 50)
If $data <> "" Then
UDPCloseSocket($socket1)
UDPShutdown()
$Timen=StringSplit($data,",")
SetLocalTime($Timen,$Timen,$Timen,$Timen,$Timen,$Timen)
EndIf
WEnd
EndIf
EndIf
Next
EndIf
Func SetLocalTime($Hour, $Min, $Sec =0,$Year = 0,$Month = 0,$Day = 0)
Local $Error = 0
Local $Return = False
If $Hour < 0 Or $Hour > 23 Then $Error = 1
If $Min < 0 Or $Min > 59 Then $Error = 1
If $Sec < 0 Or $Sec > 59 Then $Error = 1
If @NumParams > 3 And ($Day < 1 Or $Day > 31) Then $Error = 1
If @NumParams > 4 And ($Month < 1 Or $Month > 12) Then $Error = 1
If @NumParams > 5 And ($Year < 1601 Or $Year > 30827) Then $Error = 1
If Not $Error Then
Local $Struct = DLLStructCreate('Short;Short;Short;Short;Short;Short;Short;Short')
Local $StructPtr = DLLStructGetPtr($Struct)
If @NumParams < 6 Then
DLLCall('Kernel32', 'None', 'GetLocalTime', 'Ptr', $StructPtr)
If @Error Then $Error = 2
EndIf
If Not $Error Then
DLLStructSetData($Struct, 5, $Hour)
DLLStructSetData($Struct, 6, $Min)
DLLStructSetData($Struct, 7, $Sec)
DLLStructSetData($Struct, 8, 0)
If @NumParams > 3 Then DLLStructSetData($Struct, 4, $Day)
If @NumParams > 4 Then DLLStructSetData($Struct, 2, $Month)
If @NumParams > 5 Then DLLStructSetData($Struct, 1, $Year)
DLLCall('Kernel32', 'None', 'SetLocalTime', 'Ptr', $StructPtr)
Local $Result = DLLCall('Kernel32', 'Int', 'SetLocalTime', 'Ptr', $StructPtr)
If @Error Then
$Error = 2
Else
$Return = ($Result <> 0)
EndIf
EndIf
EndIf
SetError($Error)
Return $Return
EndFunc
[ 本帖最后由 bing614 于 2008-5-26 00:02 编辑 ] 原帖由 bing614 于 2008-5-26 00:00 发表 http://www.autoitx.com/images/common/back.gif
以前也做过这方面的实验,发代码上来大家研究一下,代码是修改的 titer 兄弟发的 局域网内客户端自动连接服务端所以客户机不需要指定服务器IP地址 http://www.autoitx.com/forum.php?mod=viewthread&tid=811&extra=page%3D ...
感谢.
我测试的时候,cpu占用率很高. 其实还可以这样做时间同步的
就是在服务器上装个mssql,然后客户机去连接这个数据库,就可以获得时间了
这样的好处是,就算客户端有几百个,也不会有太大的问题
[ 本帖最后由 ken0137 于 2008-5-28 14:08 编辑 ] 没有加退出,肯定占用CPU.重新发
$objWMIService = ObjGet("winmgmts:\\localhost\root\CIMV2")
$colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_NetworkAdapterConfiguration WHERE IPEnabled != 0", "WQL", 0x10 + 0x20)
If IsObj($colItems) then
For $objItem In $colItems
Dim $netmask=""
$localIP=$objItem.IPAddress(0)
$ip=StringSplit($localIP,".")
$net=StringSplit($objItem.IPSubnet(0),".")
For $i=1 To $ip
If $i = $ip Then
$netmask=$netmask&BitOR($ip[$i],BitXOR($net[$i],255))
Else
$netmask=$netmask&BitOR($ip[$i],BitXOR($net[$i],255))&"."
EndIf
Next
If Ping($netmask,10) Then
UDPStartup()
$socket = UDPOpen($netmask, 8410)
$socket1 = UDPBind($localIP,8411)
$status = UDPSend($socket, "client:"&$localIP )
If $status <> 0 then
UDPCloseSocket($socket)
While 1
$data = UDPRecv($socket1, 50)
If $data <> "" Then
UDPCloseSocket($socket1)
UDPShutdown()
$Timen=StringSplit($data,",")
SetLocalTime($Timen,$Timen,$Timen,$Timen,$Timen,$Timen)
Exit
EndIf
WEnd
EndIf
EndIf
Next
EndIf
Func SetLocalTime($Hour, $Min, $Sec =0,$Year = 0,$Month = 0,$Day = 0)
Local $Error = 0
Local $Return = False
If $Hour < 0 Or $Hour > 23 Then $Error = 1
If $Min < 0 Or $Min > 59 Then $Error = 1
If $Sec < 0 Or $Sec > 59 Then $Error = 1
If @NumParams > 3 And ($Day < 1 Or $Day > 31) Then $Error = 1
If @NumParams > 4 And ($Month < 1 Or $Month > 12) Then $Error = 1
If @NumParams > 5 And ($Year < 1601 Or $Year > 30827) Then $Error = 1
If Not $Error Then
Local $Struct = DLLStructCreate('Short;Short;Short;Short;Short;Short;Short;Short')
Local $StructPtr = DLLStructGetPtr($Struct)
If @NumParams < 6 Then
DLLCall('Kernel32', 'None', 'GetLocalTime', 'Ptr', $StructPtr)
If @Error Then $Error = 2
EndIf
If Not $Error Then
DLLStructSetData($Struct, 5, $Hour)
DLLStructSetData($Struct, 6, $Min)
DLLStructSetData($Struct, 7, $Sec)
DLLStructSetData($Struct, 8, 0)
If @NumParams > 3 Then DLLStructSetData($Struct, 4, $Day)
If @NumParams > 4 Then DLLStructSetData($Struct, 2, $Month)
If @NumParams > 5 Then DLLStructSetData($Struct, 1, $Year)
DLLCall('Kernel32', 'None', 'SetLocalTime', 'Ptr', $StructPtr)
Local $Result = DLLCall('Kernel32', 'Int', 'SetLocalTime', 'Ptr', $StructPtr)
If @Error Then
$Error = 2
Else
$Return = ($Result <> 0)
EndIf
EndIf
EndIf
SetError($Error)
Return $Return
EndFunc
结贴...
还是打回原形,用dos命令行了... 奇思妙想诚可贵,任督两脉亦要通! net time..也看看。