如何用最简单的方法,取得局域网中的另一台机器的时间,Winform
假设另一台机器一直在线

解决方案 »

  1.   

    是用这台机器做服务器吗?
    这台机器有数据库吗?
    如果是的话可以用SQL语句实现
      

  2.   

    使用命令
    net time \\192.168.16.2不过会发生拒绝访问的问题,你要保证有权限访问。
      

  3.   

    net time \\192.168.16.2不过会发生拒绝访问的问题,你要保证有权限访问。
    如果不登陆就会有些问题
    还有更好的方法吗?
      

  4.   

    也许可以考虑自己实现RFC 867的协议。
      

  5.   

    RFC 868                                                         May 1983
    Time Protocol                                                           
    When used via UDP the time service works as follows:   S: Listen on port 37 (45 octal).   U: Send an empty datagram to port 37.   S: Receive the empty datagram.   S: Send a datagram containing the time as a 32 bit binary number.   U: Receive the time datagram.   The server listens for a datagram on port 37.  When a datagram
       arrives, the server returns a datagram containing the 32-bit time
       value.  If the server is unable to determine the time at its site, it
       should discard the arriving datagram and make no reply.The TimeThe time is the number of seconds since 00:00 (midnight) 1 January 1900
    GMT, such that the time 1 is 12:00:01 am on 1 January 1900 GMT; this
    base will serve until the year 2036.For example:   the time  2,208,988,800 corresponds to 00:00  1 Jan 1970 GMT,             2,398,291,200 corresponds to 00:00  1 Jan 1976 GMT,             2,524,521,600 corresponds to 00:00  1 Jan 1980 GMT,             2,629,584,000 corresponds to 00:00  1 May 1983 GMT,        and -1,297,728,000 corresponds to 00:00 17 Nov 1858 GMT.
      

  6.   

    让你看看可不可能,呵呵。昨天晚上写的,测试通过。/// <summary>
            /// 获取服务器的网络时间,并转换为东8区时间
            /// </summary>
            /// <returns>调用成果返回服务器的网络时间,失败返回System.DateTime.MinValue</returns>
            public System.DateTime GetServerDateTime()
            {
                System.DateTime ret;
                int nSize;            ret = System.DateTime.MinValue;            byte[] RecvBuf = new byte[1024];
                //byte[] SendBuf = new byte[0];
                RecvBuf.Initialize();            IPEndPoint ServerEp = new IPEndPoint(IPAddress.Parse(FServerAddress),FPort);            using (System.Net.Sockets.Socket Time_Socket = new Socket(AddressFamily.InterNetwork,
                        SocketType.Stream,
                        ProtocolType.IP))
                {
                    Time_Socket.Connect(ServerEp);
                    //Time_Socket.Send(SendBuf);
                    nSize = Time_Socket.Receive(RecvBuf);                Time_Socket.Close();
                }            if (nSize ==4)//接收到一个32位的整型
                {
                    try
                    {
                        // 为了演示完整过程,这里将Byte数组转换为网络序列的long型,方便调用NetworkToHostOrder函数。
                        // 这里也可以不调用NetworkToHostOrder函数,而直接拼成主机序列,
                        StringBuilder sbValue = new StringBuilder();
                        sbValue.AppendFormat("{0:X2}{1:X2}{2:X2}{3:X2}00000000", RecvBuf[3], RecvBuf[2], RecvBuf[1], RecvBuf[0]);
                        long ServerSecs = long.Parse(sbValue.ToString(), System.Globalization.NumberStyles.HexNumber);                    // 这里转换网络字节序为主机字节序
                        ServerSecs = System.Net.IPAddress.NetworkToHostOrder(ServerSecs);
                        
                        // The ServerSecs is the number of seconds since 00:00 (midnight) 1 January 1900 GMT
                        ret = DateTime.Parse("1900-01-01 00:00:00");
                        ret = ret.AddSeconds(ServerSecs);
                        ret = ret.AddHours(8);  // 转换为东8区时间                }
                    catch (Exception e)
                    {
                        Console.WriteLine(e.Message);
                    }
                    
                }
      

  7.   

    楼上的,我按你的代码做了一些小改动,不能运行呀,为什么
    /// <summary>
    /// 获取服务器的网络时间,并转换为东8区时间
    /// </summary>
    /// <returns>调用成果返回服务器的网络时间,失败返回System.DateTime.MinValue</returns>
    public static System.DateTime GetServerDateTime()
    {
    System.DateTime ret;
    int nSize; ret = System.DateTime.MinValue; byte[] RecvBuf = new byte[1024];
    //byte[] SendBuf = new byte[0];
    RecvBuf.Initialize(); IPEndPoint ServerEp = new IPEndPoint(IPAddress.Parse("192.168.1.101"),7000); 
    #############333在上边的一行就报错,说什么主机积极拒绝连接??? using (System.Net.Sockets.Socket Time_Socket = new Socket(AddressFamily.InterNetwork,
       SocketType.Stream,
       ProtocolType.IP))
    {
    Time_Socket.Connect(ServerEp);
    //Time_Socket.Send(SendBuf);
    nSize = Time_Socket.Receive(RecvBuf); Time_Socket.Close();
    } if (nSize ==4)//接收到一个32位的整型
    {
    try
    {
    // 为了演示完整过程,这里将Byte数组转换为网络序列的long型,方便调用NetworkToHostOrder函数。
    // 这里也可以不调用NetworkToHostOrder函数,而直接拼成主机序列,
    StringBuilder sbValue = new StringBuilder();
    sbValue.AppendFormat("{0:X2}{1:X2}{2:X2}{3:X2}00000000", RecvBuf[3], RecvBuf[2], RecvBuf[1], RecvBuf[0]);
    long ServerSecs = long.Parse(sbValue.ToString(), System.Globalization.NumberStyles.HexNumber); // 这里转换网络字节序为主机字节序
    ServerSecs = System.Net.IPAddress.NetworkToHostOrder(ServerSecs);
                        
    // The ServerSecs is the number of seconds since 00:00 (midnight) 1 January 1900 GMT
    ret = DateTime.Parse("1900-01-01 00:00:00");
    ret = ret.AddSeconds(ServerSecs);
    ret = ret.AddHours(8);  // 转换为东8区时间 }
    catch (Exception e)
    {
    Console.WriteLine(e.Message);
    }
                    
    }
    MessageBox.Show(ret.ToString());
    return ret;
    }
      

  8.   

    最新的函数实现可以去这里 http://spaces.msn.com/members/yuanreid/请检查一下对方的机器是否运行了支持RFC868的服务,另外该协议的默认端口应该是Tcp或udp的37端口。
    而且你所说的错误提示,应该发生在Time_Socket.Connect(ServerEp);才对,请再检查一下吧。
      

  9.   

    要怎么样才能运行了支持RFC868的服务
      

  10.   

    IPEndPoint ServerEp = new IPEndPoint(IPAddress.Parse("192.168.1.101"),7000); 
    这是连 我自己本机的,有什么问题吗?yuanreid(闲云孤鹤) 
    你的代码中这句话IPEndPoint ServerEp = new IPEndPoint(IPAddress.Parse(FServerAddress),FPort);中的FServerAddress,与Fport中怎么赋值的?
      

  11.   

    远程处理示例:动态发布请参见
    远程处理示例 | RemotingServices.Marshal 方法 | RemotingServices.Disconnect 方法 | ChannelServices.UnregisterChannel 方法
    对于服务器激活的可远程处理的类型,.NET 远程处理仅支持默认构造函数。如果要在使用某个特定构造函数创建对象后发布该对象并且完全控制该特定实例的发布,可以通过编程方式发布该实例。警告   .NET 远程处理在默认情况下不进行身份验证或加密。因此,建议您在与客户端或服务器进行远程交互之前,采取任何必要的措施确认它们的身份。因为 .NET 远程处理应用程序需要 FullTrust 权限才能执行,所以未经授权的客户端如果被授予了访问您的服务器的权限,该客户端就可能像完全受信任的客户端一样执行代码。应始终验证终结点的身份并将通信流加密,通过在 Internet 信息服务 (IIS) 中承载远程类型,或者通过生成自定义通道接收对来完成这项工作。
    编译和运行该示例 在命令提示处键入以下命令: 
    vbc -t:library remote.vb vbc -r:System.Runtime.Remoting.dll -r:remote.dll server.vb vbc -r:System.Runtime.Remoting.dll -r:remote.dll client.vb 打开两个指向同一目录的命令提示。在其中一个键入 server。在另一个键入 client。 
    若要分步取消发布该可远程处理对象,请在服务器命令提示下按 ENTER 键并重新运行客户端以观察为不同步骤引发的不同异常。该应用程序可在单台计算机上运行或通过网络运行。如果要在网络上运行该应用程序,必须用远程计算机的名称替换客户端配置中的“localhost”。remote.vb
    Imports SystemPublic Class ServiceClass
       Inherits MarshalByRefObject   Private m_starttime As DateTime   Public Sub New()
          Console.WriteLine("ServiceClass created without constructor. Instance hash is " & Me.GetHashCode().ToString())
          m_starttime = DateTime.Now
       End Sub      Overrides Protected Sub Finalize()
          Console.WriteLine("I'm being collected after " & (New TimeSpan(DateTime.Now.Ticks - m_starttime.Ticks)).ToString() & " seconds.")
          MyBase.Finalize()
       End Sub       Public Function GetServerTime() As DateTime
          Console.WriteLine("Time requested by a client.")
          Return DateTime.Now
       End Function      Public ReadOnly Property InstanceHash() As Integer
          Get
             Return Me.GetHashCode()
          End Get
       End Property End Class
    Server.vb
    Imports System
    Imports System.Runtime.Remoting
    Imports System.Runtime.Remoting.Channels
    Imports System.Runtime.Remoting.Channels.HttpPublic Class ServerProcess
       <MTAThread()> _
       Public Shared Sub Main()      Dim channel As New HttpChannel(8080)
          ChannelServices.RegisterChannel(channel)      Dim object1 As New ServiceClass()      ' Creates the single instance of ServiceClass. All clients
          ' will use this instance.
          Dim ref1 As ObjRef = RemotingServices.Marshal(object1, "object1uri")
          Console.WriteLine("ObjRef.URI: " & ref1.URI)      Console.WriteLine("Running. Press Enter to end publication.")
          Console.ReadLine()      ' This unregisters the object from publication, but leaves
          ' the channel listening.
          RemotingServices.Disconnect(object1)
          Console.WriteLine()
          Console.WriteLine("Disconnected the object. Client now receives a RemotingException.")
          Console.WriteLine("Press Enter to unregister the channel.")
          Console.ReadLine()
          ' At this point, the ServerClass object still exists. The server
          ' could republish it.      ' This unregisters the channel, but leaves the application 
          ' domain running.
          ChannelServices.UnregisterChannel(channel)
          Console.WriteLine("Unregistered the channel. Client now receives a WebException.")
          ' The ServerClass object still exists. The server could
          ' reregister the channel and republish the object.
          Console.WriteLine("The host application domain is still running. Press Enter to stop the process.")
          Console.ReadLine()      ' The ServiceClass object's Finalize method writes a message to
          ' the console. A single object will almost always succeed in 
          ' running its Finalize method before the Console is finalized;
          ' in a larger application, you could ensure that all objects 
          ' finalize before the application ends by calling the garbage 
          ' collector and waiting.
          GC.Collect()
          GC.WaitForPendingFinalizers()
       End Sub
       
    End Class
    Client.vb
    Imports System 
    Imports System.Runtime.Remoting
    Imports System.Runtime.Remoting.Channels
    Imports System.Runtime.Remoting.Channels.Tcp
    Imports System.Runtime.Remoting.Channels.HttpPublic Class ClientProcess
       <MTAThread()> _
       Public Shared Sub Main()
          
          Dim channel As New HttpChannel(0)
          ChannelServices.RegisterChannel(channel)      ' Registers the remote class. (This could be done with a
          ' configuration file instead of a direct call.)
          RemotingConfiguration.RegisterWellKnownClientType(Type.GetType("ServiceClass, remote"), "http://localhost:8080/object1uri")      ' Instead of creating a new object, this obtains a reference
          ' to the server's single instance of the ServiceClass object.
          Dim object1 As ServiceClass = New ServiceClass()      Try
             Console.WriteLine("ServerTime: " & object1.GetServerTime())
          Catch ex As Exception
             Console.WriteLine("Exception of type: " & ex.GetType.ToString & " occurred.")
             Console.WriteLine("Details: " & ex.Message)
          End Try   End Sub     ' Main
    End Class   ' ClientProcess
      

  12.   

    to  whmjw(明年今日十年之后)
    我的代码是写成一个不可见的控件了,FPort和FServerAddress都是控件的属性,由使用者进行赋值。其中FPort的默认值为37。另外见很多人反映,运行后无法进行Socket连接,这是由于对端的网络时间服务不存在,我是自己写了一个网络时间的服务器自己测试用,同时还使用了一台IBM AIX的小型机进行测试,是没有问题的。
      

  13.   

    用一个线程,调用net time....
      

  14.   

    命令行net time,是访问Windows Time服务的,很多UNIX服务器是不支持的。而RFC868是标准的网络时间协议,所有的UNIX包括Linux都是默认支持的。
      

  15.   

    感谢楼上各位的回答我现在就是Remoting来实现的,不过有点占服务器资源了,毕竟需要每隔一秒钟去连接服务器,序列化与反序列化需要时间与服务器资源,我们的程序是7X24小时不间断运行,所以我就想可不可以实现从客户端直接到得服务器的时间.而又不太占服务器的资源.另外见很多人反映,运行后无法进行Socket连接,这是由于对端的网络时间服务不存在,我是自己写了一个网络时间的服务器自己测试用,同时还使用了一台IBM AIX的小型机进行测试,是没有问题的。自己写网络时间服务器,怎么 写??
      

  16.   


     另外 我是这样赋值的IPEndPoint ServerEp = new IPEndPoint(IPAddress.Parse("192.168.0.70"),37);192.168.0.90是我本机的IP 运行到Time_Socket.Connect(ServerEp);这里就报错了,是不是本机没有安装什么时间服务器之类的东西?感谢 yuanreid(闲云孤鹤)的回答:),请好人做到底吧
      

  17.   

    网络时间协议在UNIX平台普遍都支持。在windows平台上,微软自己搞了windows time这样的服务,不是标准的rfc868协议。在C++Buidler下有Indy的网络时间服务控件,可以直接实现一个rfc868网络时间服务器。
    也可以自己通过Socket编程,创建一个TCP的服务器,一旦有连接就发送当前的本机时间到对端。协议见下方:When used via TCP the time service works as follows:   S: Listen on port 37 (45 octal).   U: Connect to port 37.   S: Send the time as a 32 bit binary number.   U: Receive the time.   U: Close the connection.   S: Close the connection.   The server listens for a connection on port 37.  When the connection
       is established, the server returns a 32-bit time value and closes the
       connection.  If the server is unable to determine the time at its
       site, it should either refuse the connection or close it without
       sending anything.另外,这个时间是标准时区的时间才符合协议。
    The time is the number of seconds since 00:00 (midnight) 1 January 1900
    GMT, such that the time 1 is 12:00:01 am on 1 January 1900 GMT; this
    base will serve until the year 2036.而且到2036年,这个协议就无法使用了,因为32bit已经越界了吧。呵呵!
    想知道自己的机器上是否有标准的rfc868协议的服务器很简单。只要用netstat看看37端口是否有服务在listen就知道了。比如 用 netstat -a命令
    TCP    hostname:time           hostname:0              LISTENING这行显示的就是37端口,因为37端口是默认的time服务,所以这里显示成time了。