2010-09-20 35 views
12

Tôi đang thêm nhiều người chơi được nối mạng vào trò chơi tôi đã thực hiện. Khi máy chủ gửi gói cập nhật cho máy khách, tôi bao gồm dấu thời gian để máy khách biết chính xác khi nào thông tin đó hợp lệ. Tuy nhiên, máy tính của máy chủ và máy khách có thể có đồng hồ được đặt ở các thời điểm khác nhau (có thể chỉ là một vài giây khác biệt), do đó dấu thời gian từ máy chủ cần được dịch sang giờ địa phương của khách hàng.Đo chênh lệch thời gian giữa các thiết bị được nối mạng

Vì vậy, tôi muốn biết cách tốt nhất để tính chênh lệch thời gian giữa máy chủ và máy khách. Hiện tại, khách hàng ping máy chủ cho một dấu thời gian trong quá trình khởi tạo, cần lưu ý khi nào yêu cầu được gửi đi và khi nó được trả lời, và đoán rằng dấu thời gian được tạo gần nửa chặng đường. Khách hàng cũng điều hành 10 thử nghiệm này và lấy mức trung bình.

Nhưng, vấn đề là tôi nhận được kết quả khác nhau trong các lần chạy lặp lại của chương trình. Trong mỗi bộ 10, mỗi phép đo hiếm khi phân kỳ hơn 400 mili giây, có thể chấp nhận được. Nhưng nếu tôi đợi một vài phút giữa mỗi lần chạy chương trình, kết quả trung bình có thể không đồng ý bằng 2 giây, điều này là không thể chấp nhận được.

Có cách nào tốt hơn để tìm ra sự khác biệt giữa đồng hồ của hai thiết bị được nối mạng không? Hoặc là có ít nhất một cách để tinh chỉnh thuật toán của tôi để mang lại kết quả chính xác hơn?

Chi tiết có thể có hoặc không liên quan: Các thiết bị là iPod Touch giao tiếp qua Bluetooth. Tôi đang đo ping để ở bất cứ đâu từ 50-200 mili giây. Tôi không thể yêu cầu người dùng đồng bộ hóa đồng hồ của họ. :)


Cập nhật: Với sự giúp đỡ của các câu trả lời dưới đây, tôi đã viết một lớp khách quan để xử lý việc này. Tôi đã đăng nó lên blog của mình: http://scooops.blogspot.com/2010/09/timesync-was-time-sink.html

Trả lời

23

Gần đây tôi đã tham gia một lớp học một giờ về điều này và nó không đủ dài, nhưng tôi sẽ cố gắng đun sôi nó xuống để giúp bạn chỉ đúng hướng. Hãy sẵn sàng cho một đại số nhỏ.

Cho s bằng thời gian theo máy chủ. Hãy c bằng thời gian theo khách hàng. Để d = s - c. d là những gì được thêm vào thời gian của khách hàng để sửa nó thành thời gian của máy chủ, và là những gì chúng ta cần phải giải quyết.

Trước tiên, chúng tôi gửi gói từ máy chủ đến máy khách với dấu thời gian. Khi gói tin đó được nhận tại máy khách, nó lưu trữ sự khác biệt giữa dấu thời gian cụ thể và đồng hồ riêng của nó là t1.

Máy khách sau đó gửi một gói tin đến máy chủ bằng dấu thời gian của riêng nó. Máy chủ gửi sự khác biệt giữa dấu thời gian và đồng hồ riêng của nó trở lại máy khách dưới dạng t2.

Lưu ý rằng t1 và t2 đều bao gồm thời gian "di chuyển" t của gói cộng với chênh lệch thời gian giữa hai đồng hồ d.Giả sử cho khoảnh khắc đó thời gian đi lại là như nhau trong cả hai hướng, bây giờ chúng tôi có hai phương trình trong hai ẩn số, có thể được giải quyết:

t1 = t - d 
t2 = t + d 
t1 + d = t2 - d 
d = (t2 - t1)/2 

Bí quyết đi vì thời gian đi lại không phải lúc nào cũng ổn định, được minh chứng bởi ping của bạn từ 50 đến 200 ms. Hóa ra chính xác nhất là sử dụng dấu thời gian với thời gian ping tối thiểu. Đó là bởi vì thời gian ping của bạn là tổng của sự chậm trễ "kim loại trần" cộng với bất kỳ sự chậm trễ nào đã chờ đợi trong hàng đợi bộ định tuyến. Mỗi một lần trong một thời gian, một gói may mắn được thông qua mà không có bất kỳ sự chậm trễ xếp hàng, vì vậy bạn sử dụng thời gian tối thiểu đó là thời gian lặp lại nhiều nhất.

Cũng xin lưu ý rằng đồng hồ chạy ở các mức giá khác nhau. Ví dụ, tôi có thể thiết lập lại máy tính của tôi ở nhà đến mili giây và một ngày sau đó nó sẽ là 8 giây chậm. Điều đó có nghĩa là bạn phải liên tục điều chỉnh d. Bạn có thể sử dụng độ dốc của các giá trị khác nhau của d tính theo thời gian để tính toán độ trôi của bạn và bù cho nó ở giữa các phép đo, nhưng đó là ngoài phạm vi của một câu trả lời ở đây.

Hy vọng sẽ giúp chỉ cho bạn đúng hướng.

+0

Wow! Cảm ơn! Đó chính xác là những gì tôi đang tìm kiếm. Nó không hoàn toàn rõ ràng với tôi nhưng tại sao nó tốt hơn so với phương pháp ban đầu của tôi (mặc dù tôi tin rằng nó là), nhưng tôi sẽ đăng lại ở đây khi tôi thử nó. Tôi không nghĩ rằng tôi sẽ cần phải điều chỉnh d trong suốt một phiên chơi game, nhưng nó không phải là khó để làm gì nếu tôi cần. Cảm ơn một lần nữa! – whooops

+0

Điều này đã hoạt động rất tốt. Tôi thấy rằng nếu tôi luôn nhận các giá trị nhỏ nhất (tức là, tiêu cực nhất) t1 và t2, nó giống như việc lấy các ping nhỏ nhất, do đó nó hội tụ trên độ lệch chính xác. Tôi đã t1 = tem client - server tem và t2 = tem máy chủ - tem client Ngoài ra, tôi đã phát hiện ra rằng iphones trôi dạt khá đáng kể! Trong vòng nửa giờ, độ lệch thực tế giữa hai thiết bị có thể thay đổi nhiều đến nửa giây. Tôi đã xác minh điều này với các chương trình đồng hồ liên lạc với các máy chủ NTP. – whooops

+0

Rất vui được giúp ích cho bạn. –

2

Thuật toán của bạn sẽ không chính xác hơn trừ khi bạn có thể sử dụng một số phương pháp thống kê. Trước hết, 10 có lẽ không đủ. Sự thay đổi đầu tiên và đơn giản nhất là thu thập 100 mẫu thời gian vận chuyển và tung ra x dài nhất và ngắn nhất.

Một điều cần thêm là cả hai khách hàng sẽ gửi dấu thời gian của riêng họ trong mỗi gói. Sau đó, bạn cũng có thể tính toán các đồng hồ của chúng khác nhau như thế nào và kiểm tra sự khác biệt trung bình giữa các đồng hồ.

Bạn cũng có thể kiểm tra cụ thể về triển khai STNP và NTP, vì các giao thức này thực hiện cụ thể điều này.

+0

Cảm ơn. Tôi nghĩ rằng tôi sẽ thử các thuật toán được đưa ra bởi câu trả lời ở trên, và đưa lời khuyên của bạn về việc sử dụng nhiều mẫu. – whooops

Các vấn đề liên quan