drop zone

Share files, chat, and remote terminal with your friends in the LAN network. Easy to use and zero-configuration.

Đọc phần description chắc các bạn cũng nắm được sơ sơ nó làm gì rồi nhỉ :)) “truyền nhận files” phiên bản friendly + bonus thêm tính năng chat và remote terminal. Thực ra nó chả khác gì bài tập hồi sinh viên thầy hay bắt các bạn làm đâu :)) Lý do tôi viết cái tool này chỉ đơn giản “cuối tuần rảnh viết chơi” :)) Còn về tên DropZone, đừng hỏi tôi, tôi cũng không biết tại sao mình lại đặt tên con mình như thế nữa :/

Gửi nhận files

Để làm cho nó friendly hơn chúng ta cần làm được:

  1. Có giao diện, kéo thả file hoặc folder….
  2. Không cần nhập IP.
  3. Không cần quan tâm ai là client ai là server.

Đây là các solutions tôi bịa ra để giải quyết từng vấn đền bên trên:

  1. Tôi sử dụng C# wpf để code (lý do là tôi chuyên C# hơn java 1 chút :v)
  2. Tôi sẽ sử dụng giao thức UDP để boardcast 1 message, nhiệm vụ của message này là thông báo cho DropZone trên các máy khác là “alo, là Gin đây, tôi đang online nhé anh em”. Khi tôi nhận được một message như thế này, tôi sẽ lưu vào 1 danh sách “bạn bè online”. Để làm mới danh sách thì tôi phải liên tục đọc các boardcast messages như vầy, đồng thời còn phải sử dụng 1 timer để send boardcast message này định kỳ vài giây 1 lần cho các “anh em” khác trên mạng LAN biết rằng tôi còn “sống”.
  3. Cái này thì đơn giản, cho nó “lưỡng tính” là được, vừa là client vừa là server :))

UI

Sau một hồi loay hoay thì tôi cũng viết được cái UI như hình:

Còn về tính năng drag drop thì chỉ cần set AllowDrop="True" và code behind như sau:

protected override void OnDrop(DragEventArgs e)
{
    var files = (string[])e.Data.GetData(DataFormats.FileDrop);
    HandleFiles(files);
}

Online friends

Cái này gồm 2 phần chính là send boardcast message và nhận broadcast message (cụ thể ở đây).

  1. Send boardcast message, hàm này sẽ được gọi mỗi 3s để thông báo cho các “anh em” trong mạng rằng nó đang còn sống.
    var header = new PingInfo { ...... }.BuildMessage();
    var bytes = Encoding.UTF8.GetBytes(header);
    await _client.SendAsync(bytes, bytes.Length, "255.255.255.255", Constants.StationPort);
    
  2. Receive boardcast message
    while (true)
    {
     var from = new IPEndPoint(IPAddress.Any, 0);
     var buffer = _client.Receive(ref from);
     var header = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
    
     var pingInfo = PingInfo.Parse(header);
     var address = from.Address.ToString();
     // update online friend list
    }
    

Dựa vào danh sách online friends, tôi có thể show ra một menu cho người dùng chọn địa chỉ cần gửi file đến hoặc nếu người dùng drag drop files vào tool thì tool của tôi sẽ gửi cho toàn bộ danh sách đang online.

Chat

Tính năng này là hàng bonus thêm vào thôi :)) tính năng này tôi viết không có gì cao siêu so với code hồi sinh viên :)) gửi nhận chuỗi string thế thôi :)). Chỉ tốn thời gian ở phần UI, loay hoay cả buổi tôi mới code được phần này :/ Nhưng theo con mắt thẩm mỹ của tôi thì UI cũng không tệ lắm :))

Remote Ternimal

Nghe thì cao siêu chứ thực ra chẳng có vẹo gì đâu :)). Yêu cầu của nó là máy bên A sẽ mở 1 cửa sổ để gửi 1 câu lệnh cho máy bên B thực thi, output của câu lệnh thực thi ở máy bên B sẽ được show ở máy bên A. Một số vấn đề gặp phải và cách giải quyết:

  1. Làm sao gửi lệnh từ máy A cho máy B: điều kiện là 2 máy đều phải chạy DropZone, máy A sẽ gửi 1 message chứa tên lệnh cho máy B thông qua TCP socket. Máy B nhận được sẽ thực thi lệnh đó rồi gửi output lại cho máy A thông qua socket hiện tại.
  2. Show output realtime?? -> Redirect output của câu lệnh thực thi sang output stream mình đang control, mình sẽ chờ và đọc output từ đây -> khi lệnh thực thi ghi ra output stream thì mình sẽ đọc từ đây và gửi lại cho máy A thông qua socket.

Và đây là thành quả (làm quả terminal tợ tợ ubuntu tốn tgian phết :)) )

Chốt

Toàn bộ source code các bạn có thể xem ở đây: https://github.com/sontx/dropzone

Còn đây là toàn bộ thành quả:

PS: nếu các bạn đọc hết và nhứt mắt vì lỗi sai chính tả của tôi thì tôi vô cùng xin lỗi nhé :))


Copyright © 2022. All rights reserved.