Toggle Theme Editor
Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate Charcoal

Hỏi cách đồng bộ thời gian của client từ server?

Discussion in 'Xây dựng ứng dụng server-client desktop' started by xuho, 30/5/16.

  1. xuho

    xuho New Member

    Xin chào mọi người trong diễn đàn, hiện tại em đang làm một số bài tập về lập trình client-server sử dụng socket. Em gặp một bài toán có yêu cầu như sau: cài đặt các lớp client và server(server hỗ trợ nhiều kết nối), mỗi client sẽ đồng bộ thời gian từ server 1 phút một lần(Em đang thắc mắc cái này ạ), tiếp nữa là client gửi 1 request(chẳng hạn là 1 xâu ký tự) server trả về thời gian hiện tại của hệ thống + độ trễ gói tin.

    Vậy mong mọi người chỉ cho em cách làm với ạ. Em xin cám ơn.
     
  2. JackV

    JackV Administrator Staff Member

    Mỗi client sẽ đồng bộ thời gian từ server 1 phút một lần -> Tức là mỗi 1 phút client sẽ kiểm tra giờ của server để update một lần.

    Độ trễ gói tin ->
    Độ trễ xử lý = thời gian nhận gói tin - thời gian nhận gói tin
    Độ trễ gởi nhận = thời gian nhận gói tin - thời gian gởi gói tin

    Đó là lý thuyết, không biết bạn gặp khó khăn gì!!!
     
    xuho likes this.
  3. xuho

    xuho New Member

    Cám ơn admin đã trả lời.
    Em thắc mắc ở chỗ đồng bộ thời gian ạ.
    Giờ em dùng dùng lớp Calendar để lấy thời gian trên server trả về cho client thôi đúng không ạ?
    Để client cứ 1p gửi request cho việc đồng bộ một lần thì em dùng:
    while(true){
    //gửi request
    Sleep(60*1000);
    }
    Như này đúng ko ạ?

    Còn thời gian trễ em tính như này:
    lấy giá trị lúc gửi gói tin từ client: long timeAtClient = System.currentTimeMillis();// gửi thằng này lên server luôn
    lúc server nhận gói tin thì lấy thời gian nhận gói tin: long timeAtServer = System.currentTimeMillis();
    sau đó em lấy timeAtServer - timeAtClient sẽ ra độ trễ gói tin đúng chưa ạ?
     
  4. JackV

    JackV Administrator Staff Member

    Có một vấn đề là như thế này, bạn test trên server local thì ok nhưng nếu server khác thì có thể xảy ra vấn đề là time của client và server khác nhau do khác mũi giờ, chưa kể trường hợp client chỉnh giờ trên máy tùm lum nữa nha, suy nghĩ thêm về cái đó.

    Vấn đề khác đó là cái while true đó viết trong Thread thì ok rồi.
    Thời gian một gói tin đi bao gồm một số thời điểm 1-2-3-4
    1. Thời điểm bắt đầu chuyển gói tin lên server
    2. Thời điểm server nhận gói tin
    3. Thời điểm server bắt đầu xử lý gói tin
    4. Thời điểm server xử lý xong
    5. Thời điểm gói tin về đến client
    Độ trễ của bạn đang tính thời điểm nào đến thời điểm nào?
     
    xuho likes this.
  5. xuho

    xuho New Member

    À hình như em có hiểu sai đề: "client gửi 1 request(chẳng hạn là 1 xâu ký tự) server trả về thời gian hiện tại của hệ thống + độ trễ gói tin"
    lúc đầu em hiểu là độ trễ gói tin mà server nhận: thời điểm 2 - thời điểm 1.
    Nhưng đọc kỹ thì hình như là để yêu cầu tính độ trễ gói tin mà server gửi về cho client(như này thì hợp lý hơn). Vậy nếu như thế thì độ trễ sẽ lấy: thời điểm 5 - thời điểm 4(tức là server xử lý xong và bắt đầu gửi gói tin về).
     
  6. JackV

    JackV Administrator Staff Member

    Cho a đọc nguyên cái đề đi em
     
  7. xuho

    xuho New Member

    Dạ nguyên văn đề là như này ạ:
    Cài đặt lớp java xử lý hỗ trợ nhiều kết nối socket từ client tới server, mỗi client sẽ đồng bộ thời gian từ server 1 phut một lần, client gửi xâu "time" lên server, server trả về thời gian hiện tại của hệ thống công thêm độ trễ của gói tin, client hiển thị kết quả nhận được.
     
  8. Joe

    Joe Thành viên VIP

    It's amazing that you just asked for an algorithmic solution and instead of sharing you keep your codes for yourself.
     
    xuho likes this.
  9. xuho

    xuho New Member

    Joe likes this.
  10. Joe

    Joe Thành viên VIP

    It's normal that WE SHARE KNOWLEDGE and that's the reason I reminded you.
    The codes are OK. However I have some advice for you:
    - Global variables are needed only when
    a) other methods or inner classes need to access.
    b) referred by other classes (protected or public)
    - Buffered Input and Output make only sense when the data are processed forwards and backwards (e.g. reset, skip, etc.)

    If the aforementioned points are not the case they should be used directly. The reasons are
    - global variables must be indirectly accessed by references (e.g. Client.time) and that isn't optimal
    - Socket Communication is byte-wise and it's better to cache the data privately instead of using any buffered API
    - file, stream and socket must be closed when they are "opened"
    Example:
    PHP:
    public class Client {
        private 
    Socket socketOfClient// = null; << set in method connect() and by default it's NULL
        //private BufferedReader in = null;
        //private BufferedWriter out = null;
        
    private final int PORT 1995;
        private final 
    String HOST_NAME "localhost";
        
    //private static long thoiGianGui;
        
    public void connect() {
            
    InputStream in;
            
    OutputStream out;
            try {
                
    socketOfClient = new Socket(HOST_NAMEPORT); // << is set here

                // khoi tao luong nhap xuat
    /*
                in = new BufferedReader(new InputStreamReader(
                        socketOfClient.getInputStream()));
                out = new BufferedWriter(new OutputStreamWriter(
                        socketOfClient.getOutputStream()));
    */
                // direct usage
                
    in socketOfClient.getInputStream();
                
    out socketOfClient.getOutputStream();
                
    // gui yeu cau cho server cung voi thoi gian gui
                
    out.write("time\r\n".getBytes());
                
    //out.newLine();
                
    out.flush();
                
    thoiGianGui System.currentTimeMillis();
                
    out.write((thoiGianGui+"").getBytes());
                
    out.flush();
                
    //PrintStream ps = new PrintStream(socketOfClient.getOutputStream());
                //ps.println(thoiGianGui);
                // nhan ket qua va hien thi ra:
                //String result = in.readLine();
                
    byte[] buf = new byte[8192]; // 1 Socket buffer segment
                
    int n in.read(buf);
                
    //System.out.println("Thoi gian he thong la: " + result);
                
    System.out.println("Thoi gian he thong la: " + new String(buf0n))
            } catch (
    Exception e) {
                
    // TODO: handle exception
            
    finally // MUST BE
                
    if (socketOfClient != null) {
                       try {
                             
    in.close();
                             
    out.close();
                             
    socketOfClient.close();
                       } catch (
    Exception ex) { }
                }
            }
        }
        public static 
    void main(String[] args) {
            new 
    Client().connect();
        }
    }
     
    xuho likes this.
  11. JackV

    JackV Administrator Staff Member

    À à, hình như là hiểu cái đề này rồi, client gởi cái "time" lên server thì server sẽ trả về thời gian trên server, việc của client là hiện thị đúng như thời gian trên server đã có tính thêm khoảng thời gian trễ do mất thời gian chuyển từ server về đến client, ví dụ server trả về 9giờ 10phút 3 giây 125 mà thời gian trễ do mất thời gian chuyển về là một khoảng K = 685 thì client phải hiện thị là 9giờ 10phút 3 giây 810, đúng không bạn? Nếu đúng thì vấn đề của bạn là phải tìm cách xác định giá trị K

    Đồng bộ xong hiện thị để đó chẳng để làm gì nên mỗi phút rảnh rỗi lại lên lấy giờ mới.

    * nếu bạn hỏi xác định K như thế nào thì bạn sẽ nhận được lời khuyên "it's your duty"
     
    Last edited: 30/5/16
    xuho likes this.
  12. xuho

    xuho New Member

    Thank you so much.
     
  13. xuho

    xuho New Member

    Vâng em xin cám ơn admin. à mà cho em hỏi ngoài lề tí là admin Joe là người ngoại quốc ạ.
    Admin diễn đàn mình nhiệt tình quá, một lần nữa cám ơn các admin đã tận tình giúp đỡ em ạ.
     
  14. JackV

    JackV Administrator Staff Member

    Đúng rồi, Mr. Joe là người nước ngoài, anh ấy rất nhiệt tình với kiến thức sâu rộng.

    Xác định giá trị K như thế nào cứ nói ra anh em góp ý nhé
     
    xuho likes this.
  15. xuho

    xuho New Member

    dạ ở code em gửi có xác đinh rồi ạ :D
     
  16. JackV

    JackV Administrator Staff Member

    Vậy test thử đi, thêm code trên server nhé, sau khi server set time cho gói tin rồi thì cho sleep 5 giây để xem client xác định thời gian trễ là bao nhiêu giây nha.
     
    xuho likes this.
  17. xuho

    xuho New Member

    Dạ em cám ơn admin :D, co gì thắc mắc em sẽ lại làm phiền mọi người ạ :)
     

Chia sẻ trang này

Loading...