Công cụ bảo vệ mã nguồn .NET mạnh nhất, không thể unpack, miễn phí cho các khách hàng đầu tiên đăng ký.
Từ 1 tới 10 trên tổng số 10 kết quả

Đề tài: 2 chương trình có thể gửi thông điệp cho nhau.

  1. #1
    Ngày gia nhập
    05 2013
    Bài viết
    16

    Post 2 chương trình có thể gửi thông điệp cho nhau.

    như tiêu đề đã nói .
    e muốn hởi các pro là có cách nào có thể để 2 chương trình trao đổi thông điệp cho nhau được không ạ .
    e ví dụ dễ hiểu là khi chương trình 1 chạy thì nó gửi 1 thông điệp cho chương trình 2 . chương trình 2 tiến hành kiểm tra thông điệp của chương trình 1.
    kiểm tra thấy đúng thì chương trình 2 gửi thông điệp lại cho chương trình 1.
    đến đây chương trình 1 lại kiểm tra thông điệp của chương trình 2 nếu đúng thì sẽ truyền thông điệp cho chương trình 2.
    nó cứ tiến hành lặp đi lặp lại truyền gửi và nhận thông điệp.
    kiểu giống như server và client.
    tuy nhiên cái này không phải giữa máy chủ và máy khách. chỉ là trên cùng 1 máy thôi . không cần thông qua socket gì hết .
    Lúc đầu e tính sử dụng cách tạo file text từ chương trình. xong rồi cho nó đọc lại và kiểm tra. đúng thì xuất ra file với thông điệp cho chương trình kia xử lý.
    tuy nhiên e thấy cách này nghe có vẻ rườm rà và tốn quá nhiều thời gian để 2 chuơng trình xử lý .
    các bác có cao kiến gì xin chỉ giáo cho e được không.
    trình e chưa tới đâu nên các bác cho e source code ví dụ nha.
    e cám ơn !
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.

  2. #2
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    904

    Mình nêu hướng cho bạn làm thử xem sao.

    1. Trong phần khai báo thì định nghĩa 1 thông điệp phải lớn hơn WM_USER : #define WM_MYMESSAGE (WM_USER + 1)
    2. Khởi tạo việc gởi thông điệp đầu tiên:
    _ Tìm và lưu thẻ HWND hAnother của cửa sổ kia
    _ SendMessage(hAnother, WM_MYMESSAGE, wParam, lParam);
    3. Trong mã xử lý thông điệp WM_MYMESSAGE :
    _ Nếu là lần đầu thì tìm và lưu thẻ HWND của đối tác
    _ Kiểm tra thông điệp theo các tham số wParam và lParam
    _ Nếu đúng thì khởi tạo các tham số mới wParam2 và lParam2
    _ SendMessage(hAnother, WM_MYMESSAGE, wParam2, lParam2)

  3. #3
    Ngày gia nhập
    05 2013
    Bài viết
    16

    Trích dẫn Nguyên bản được gửi bởi MHoang Xem bài viết
    Mình nêu hướng cho bạn làm thử xem sao.

    1. Trong phần khai báo thì định nghĩa 1 thông điệp phải lớn hơn WM_USER : #define WM_MYMESSAGE (WM_USER + 1)
    2. Khởi tạo việc gởi thông điệp đầu tiên:
    _ Tìm và lưu thẻ HWND hAnother của cửa sổ kia
    _ SendMessage(hAnother, WM_MYMESSAGE, wParam, lParam);
    3. Trong mã xử lý thông điệp WM_MYMESSAGE :
    _ Nếu là lần đầu thì tìm và lưu thẻ HWND của đối tác
    _ Kiểm tra thông điệp theo các tham số wParam và lParam
    _ Nếu đúng thì khởi tạo các tham số mới wParam2 và lParam2
    _ SendMessage(hAnother, WM_MYMESSAGE, wParam2, lParam2)
    e cảm ơn nhé .
    mặc dù chưa hiểu lắm về cấu trúc chương trình ý tưởng của pro .
    để e thử cố gắng làm vấn đề này xem sao
    đây là đoạn code e tìm tên của cửa sổ chương trình trong chương trình 2
    void findct1()
    {
    HWND WINDOWFILE1 = FindWindow(TEXT("chuongtrinh1"), TEXT("open1"));
    if( WINDOWFILE1 != NULL )
    {
    // SendMessage(WINDOWFILE1, WM_MYMESSAGE, wParam2, lParam2); // có lẽ đây là vấn đề code gửi thông điệp tới chương trình 1
    }
    }
    đoạn code trong chương trình 1 như dưới:
    void findct2()
    {
    HWND WINDOWFILE2 = FindWindow(TEXT("chuongtrinh2"), TEXT("open2"));
    if( WINDOWFILE2 != NULL )
    {
    // SendMessage(WINDOWFILE2, WM_MYMESSAGE, wParam2, lParam2); // có lẽ đây là vấn đề code gửi thông điệp tới chương trình 2
    }
    }
    tuy nhiên e chưa định hình được cái thông điệp đó xử lý làm sao và làm cách nào để có thể xử lý được thông điệp đó.
    nếu có thời gian mong pro có thể hướng dẫn thêm 1 vài đoạn code nhé.

    vì e không hiểu cách thức truyền thông điệp nên cái này quả thực rất khó với e

  4. #4
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    904

    Viết cho bạn một chương trình ngắn trên VS2013 khởi động từ dự án trống.
    Khi chạy MultiWin.exe thì cửa sổ chính sẽ lưu tất cả các thể hiện khác nếu có vào danh sách.
    Khi bạn nhấn nút Start thì cửa sổ chính sẽ gởi tới tất cả các thể hiện khác một thông điệp muốn tiếp tục.
    Sau đó cửa sổ chính và từng cửa sổ khác sẽ "nói chuyện" với nhau cho tới khi một bên không muốn tiếp tục.
    Visual C++ Code:
    1. #include<Windows.h>
    2. #include<time.h>
    3. #include"resource.h"
    4. #define     MAX_WINDOW      10
    5. #define     WM_MYMESSAGE    (WM_USER+1)
    6. typedef struct
    7. {
    8.     int     cCount;                 // Hiện có bao nhiêu thể hiện
    9.     HWND    hThis;                  // Cửa sổ của thể hiện chính
    10.     HWND    hAnother[MAX_WINDOW];   // Các cửa sổ của thể hiện khác
    11. }MULTIWINDOW, *PMULTIWINDOW;
    12.  
    13. BOOL CALLBACK EnumProc(HWND hwnd, LPARAM lparam)
    14. {
    15.     PMULTIWINDOW    pMulti = (PMULTIWINDOW)lparam;
    16.     TCHAR           szCaption[MAX_PATH];
    17.  
    18.     if (pMulti->cCount >= MAX_WINDOW)
    19.         return FALSE;
    20.     GetWindowText(hwnd, szCaption, GetWindowTextLength(hwnd) + 1);
    21.     // Nếu không phải là một thể hiện của "MultiWin.exe"
    22.     if (lstrcmp(szCaption, TEXT("MultiWin")))
    23.         return TRUE;
    24.     // Nếu cửa sổ đếm được không phải là cửa sổ gọi hàm đếm thì thêm vào danh sách các cửa sổ có thể gới thông điệp tới.
    25.     if (hwnd != pMulti->hThis)
    26.     {
    27.         pMulti->hAnother[pMulti->cCount] = hwnd;
    28.         pMulti->cCount++;
    29.     }
    30.     return TRUE;
    31. }
    32. BOOL CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wparam, LPARAM lparam)
    33. {
    34.     static  HWND            hListReceive, hListWindow, hEdit;
    35.     static  MULTIWINDOW     hMulti;
    36.     TCHAR                   szText[MAX_PATH];
    37.     int                     i;
    38.  
    39.     switch (message)
    40.     {
    41.     case WM_INITDIALOG:
    42.         srand((unsigned int)time(NULL));
    43.         hListReceive = GetDlgItem(hDlg, IDC_LIST1);
    44.         hListWindow = GetDlgItem(hDlg, IDC_LIST2);
    45.         hEdit = GetDlgItem(hDlg, IDC_EDIT1);
    46.         wsprintf(szText, TEXT("%p"), hDlg);
    47.         SetWindowText(hEdit, szText);               // Hộp text thông báo thẻ của cửa sổ này
    48.  
    49.         hMulti.cCount = 0;
    50.         hMulti.hThis = hDlg;
    51.         EnumWindows(EnumProc, (LPARAM)&hMulti);     // Điền vào danh sách các cửa sổ khác
    52.         for (i = 0; i < hMulti.cCount; i++)
    53.         {
    54.             wsprintf(szText, TEXT("%p"), hMulti.hAnother[i]);
    55.             SendMessage(hListWindow, LB_ADDSTRING, 0, (LPARAM)szText);
    56.         }
    57.         return TRUE;
    58.     case WM_COMMAND:
    59.         switch (LOWORD(wparam))
    60.         {
    61.         case IDC_BUTTON1:   // Gởi tới tất cả các cửa sổ trong danh sách 1 thông điệp tiếp tục ( lparam = 1)
    62.             for (i = 0; i < hMulti.cCount; i++)
    63.                 PostMessage(hMulti.hAnother[i], WM_MYMESSAGE, (WPARAM)hDlg, (LPARAM)1);
    64.             return TRUE;
    65.         }
    66.         break;
    67.     case WM_MYMESSAGE:
    68.         TCHAR   szText[MAX_PATH];
    69.         // Xuất ra listbox diễn giải thông điệp đã nhận
    70.         wsprintf(szText, TEXT("%p : %s"), wparam, lparam ? TEXT("Continue ?") : TEXT("Go out !"));
    71.         SendMessage(hListReceive, LB_ADDSTRING, 0, (LPARAM)szText);
    72.         // Nếu kiểm tra thấy đối phương muốn tiếp tục thì gởi ngược trở lại 1 thông điệp kế tiếp
    73.         // Thông điệp này là đồng ý hay chấm dứt được lấy ngẫu nhiên.
    74.         if (lparam)
    75.             PostMessage((HWND)wparam, WM_MYMESSAGE, (WPARAM)hDlg, (LPARAM)(rand()%5));
    76.         return TRUE;
    77.     case WM_CLOSE:
    78.         EndDialog(hDlg, 0);
    79.         return TRUE;
    80.     }
    81.     return FALSE;
    82. }
    83. int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrev, LPSTR lpCmd, int nShow)
    84. {
    85.     DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), NULL, DlgProc);
    86.     return 0;
    87. }
    MultiWin.rar

  5. #5
    Ngày gia nhập
    05 2013
    Bài viết
    16

    e cảm ơn Pro nhé . mấy hôm bận làm việc quá nên quên mất phải lên diễn đàn.
    chúc Pro gặp nhiều thành công nhé.
    e sẽ cố gắng build lại chương trình phù hợp với yêu cầu e muốn.
    rất cám ơn Pro.
    thật may vì có những người hay giúp đỡ mọi người như bác .
    Đã được chỉnh sửa lần cuối bởi dinhvan115 : 03-08-2015 lúc 11:03 PM.

  6. #6
    Ngày gia nhập
    11 2007
    Nơi ở
    Hà Nội
    Bài viết
    520

    Mặc định 2 chương trình có thể gửi thông điệp cho nhau.

    Trích dẫn Nguyên bản được gửi bởi MHoang Xem bài viết
    Mình nêu hướng cho bạn làm thử xem sao.

    1. Trong phần khai báo thì định nghĩa 1 thông điệp phải lớn hơn WM_USER : #define WM_MYMESSAGE (WM_USER + 1)
    2. Khởi tạo việc gởi thông điệp đầu tiên:
    _ Tìm và lưu thẻ HWND hAnother của cửa sổ kia
    _ SendMessage(hAnother, WM_MYMESSAGE, wParam, lParam);
    3. Trong mã xử lý thông điệp WM_MYMESSAGE :
    _ Nếu là lần đầu thì tìm và lưu thẻ HWND của đối tác
    _ Kiểm tra thông điệp theo các tham số wParam và lParam
    _ Nếu đúng thì khởi tạo các tham số mới wParam2 và lParam2
    _ SendMessage(hAnother, WM_MYMESSAGE, wParam2, lParam2)
    Ý tưởng của bạn rất hay, tuy nhiên sẽ hoàn thiện hơn nếu bạn có thể send cả một khối data từ tiến trình thứ nhất sang tiến trình thứ 2.
    Các tiến trình không chia sẻ được bộ nhớ với nhau ( ngoại trừ cùng map vào một vùng nhớ chia sẻ ), do đó, nếu dùng cách SendMessage thì không thể truyền một lượng lớn dữ liệu
    mình nghĩ nên dùng memory mapping hoặc RPC để giải bài toán này.

  7. #7
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    904

    Đúng như bạn nói, cách này chỉ thông báo một vài mã hiệu qua lại lẫn nhau thôi không thể đưa con trỏ hay một chuỗi vào các tham số wParam hay lParam. Cách hay hơn là như bạn nói, dùng phân đoạn dữ liệu dùng chung với vài khai báo pragma mình cũng có làm qua vài lần, dùng memory mapping có lẽ là cách tốt nhất mình cũng đang thực hiện trong vài dự án khác. Cái RPC thì mình chưa qua bao giờ (không biết có phải là thông qua mạng không) nên chưa biết, bạn có thể cho một mẫu để anh em tham khảo không. Cám ơn bạn !!!

  8. #8
    Ngày gia nhập
    11 2007
    Nơi ở
    Hà Nội
    Bài viết
    520

    Trích dẫn Nguyên bản được gửi bởi MHoang Xem bài viết
    Đúng như bạn nói, cách này chỉ thông báo một vài mã hiệu qua lại lẫn nhau thôi không thể đưa con trỏ hay một chuỗi vào các tham số wParam hay lParam. Cách hay hơn là như bạn nói, dùng phân đoạn dữ liệu dùng chung với vài khai báo pragma mình cũng có làm qua vài lần, dùng memory mapping có lẽ là cách tốt nhất mình cũng đang thực hiện trong vài dự án khác. Cái RPC thì mình chưa qua bao giờ (không biết có phải là thông qua mạng không) nên chưa biết, bạn có thể cho một mẫu để anh em tham khảo không. Cám ơn bạn !!!
    RPC là một phuơng thức để truyền dữ liệu giữa các tiến trình khác nhau, thậm chí là giữa các máy tính khác nhau.
    Network chỉ là một dạng protocol để giao tiếp RPC thôi.

    Lập trình viên cần mô tả giao thức truyền nhận giữa các ứng dụng, gọi file mô tả này là IDL.
    dùng trình biên dịch MIDL của microsoft biên dịch IDL thành các file:
    hello.h : chứa header
    hello_s.c: chứa code để làm server
    hello_c.c: chứa code để làm client

    Dữ liệu truyền qua lại là một xâu. Client sẽ gọi hàm SayYouDo như bình thường, sau đó phần dữ liệu sẽ xuất hiện ở server. Nếu nhập QUIT ở client, server sẽ nhận tín hiệu để dừng.

    Click vào hình ảnh để lấy hình ảnh lớn

Tên:		rpc.PNG
Lần xem:	5
Size:		51.1 KB
ID:		35905

    Mình viết một đoạn code demo:

    IDL Code:
    1. // File hello.idl
    2. // Compiling hello.idl:
    3. //       midl /app_config hello.idl
    4. [
    5.    // A unique identifier that distinguishes this
    6.    // interface from other interfaces.
    7.    uuid(B0ACC031-03B0-45de-8751-D205210BA42D),
    8.  
    9.    // This is version 1.0 of this interface.
    10.    version(1.0),
    11.  
    12.    // This interface will use an implicit binding
    13.    implicit_handle(handle_t hHelloBinding)
    14. ]
    15. interface Hello
    16. {
    17.    void SayYouDo(
    18.       [in, string] const char* s // a zero-terminated string.
    19.       );
    20.  
    21.    void ShutdownRpc( void );
    22. }

    Client :
    Visual C++ Code:
    1. #include <iostream>
    2. #include <string>
    3. #include "../Protocol/hello.h"
    4. #pragma comment(lib, "Rpcrt4.lib") // RPC Functions
    5.  
    6. #if defined UNICODE || defined _UNICODE
    7. #define RPC_TSTR RPC_WSTR
    8. #else
    9. #define RPC_TSTR RPC_CSTR
    10. #endif
    11.  
    12. #define RPC_PROTOCOL         TEXT("ncacn_np")
    13. #define RPC_NETWORK_ADDRESS  (NULL)
    14. #define RPC_END_POINT        TEXT("\\pipe\\hello")
    15.  
    16. int main( int argc, char *argv[])
    17. {
    18.     RPC_STATUS status;
    19.     RPC_TSTR szStringBinding = NULL;
    20.  
    21.     // Creates a string binding handle.
    22.     status = RpcStringBindingCompose(
    23.         NULL, // UUID to bind to.
    24.         reinterpret_cast<RPC_TSTR>(RPC_PROTOCOL), //  protocol.
    25.         reinterpret_cast<RPC_TSTR>(RPC_NETWORK_ADDRESS), //  network address to use.
    26.         reinterpret_cast<RPC_TSTR>(RPC_END_POINT), // endpoint.
    27.         NULL, // Protocol dependent network options to use.
    28.         &szStringBinding); // String binding output.
    29.  
    30.     if (status)
    31.         exit(status);
    32.  
    33.     // Validates the format of the string binding handle
    34.     status = RpcBindingFromStringBinding(
    35.         szStringBinding, // The string binding to validate.
    36.         &hHelloBinding); // Put the result in the implicit binding handle
    37.  
    38.     if (status)
    39.         exit(status);
    40.  
    41.     char buf[256];
    42.     memset(buf, 0, sizeof(buf));
    43.     bool bStopped = false;
    44.     std::cout << "Enter a string and press [ENTER]. Enter QUIT to exit." << std::endl;
    45.     do
    46.     {
    47.         fgets(buf, 256, stdin);
    48.         bStopped = (strcmp(buf, "QUIT\n") == 0);
    49.         RpcTryExcept
    50.         {
    51.             SayYouDo((const unsigned char *)buf);
    52.         }
    53.         RpcExcept(1)
    54.         {
    55.             std::cerr << "Exception " << RpcExceptionCode() << std::endl;
    56.             bStopped = true;
    57.             break;
    58.         }
    59.         RpcEndExcept
    60.  
    61.     } while (!bStopped);
    62.  
    63.     // send shutdown signal
    64.     RpcTryExcept
    65.     {
    66.         // Calls the RPC function.
    67.         ShutdownRpc();
    68.     }
    69.     RpcExcept(1)
    70.     {
    71.         std::cerr << "Exception " << RpcExceptionCode() << std::endl;
    72.     }
    73.     RpcEndExcept
    74.  
    75.         // Free the memory allocated by a string.
    76.         status = RpcStringFree(
    77.         &szStringBinding); // String to be freed.
    78.  
    79.     if (status)
    80.         exit(status);
    81.  
    82.     // Releases binding handle
    83.     status = RpcBindingFree(
    84.         &hHelloBinding); // Frees the implicit binding handle
    85.  
    86.     if (status)
    87.         exit(status);
    88.  
    89.     return 0;
    90. }
    91.  
    92. // Memory allocator
    93. void* __RPC_USER midl_user_allocate(size_t size)
    94. {
    95.     return malloc(size);
    96. }
    97.  
    98. void __RPC_USER midl_user_free(void* p)
    99. {
    100.     free(p);
    101. }

    Server :
    Visual C++ Code:
    1. #include <iostream>
    2. #include "../Protocol/hello.h"
    3. #pragma comment(lib, "Rpcrt4.lib") // RPC Functions
    4.  
    5. #if defined UNICODE || defined _UNICODE
    6. #define RPC_TSTR RPC_WSTR
    7. #else
    8. #define RPC_TSTR RPC_CSTR
    9. #endif
    10.  
    11. #define RPC_PROTOCOL         TEXT("ncacn_np")
    12. #define RPC_NETWORK_ADDRESS  (NULL)
    13. #define RPC_END_POINT        TEXT("\\pipe\\hello")
    14.  
    15. HANDLE hStopEvent = NULL;
    16.  
    17. // Server functions.
    18. #ifdef __cplusplus
    19. extern "C"{
    20. #endif
    21.     void SayYouDo(const unsigned char *s)
    22.     {
    23.         std::cout << s;
    24.     }
    25.  
    26.     void ShutdownRpc( void )
    27.     {
    28.         if (hStopEvent)
    29.         {
    30.             SetEvent(hStopEvent);
    31.         }
    32.     }
    33. #ifdef __cplusplus
    34. }
    35. #endif
    36.  
    37. // Naive security callback.
    38. RPC_STATUS CALLBACK SecurityCallback(RPC_IF_HANDLE /*hInterface*/, void* /*pBindingHandle*/)
    39. {
    40.     return RPC_S_OK; // Always allow anyone.
    41. }
    42.  
    43. int main( int argc, char *argv[])
    44. {
    45.     RPC_STATUS status;
    46.  
    47.     hStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    48.     if (hStopEvent == NULL)
    49.         return 0;
    50.  
    51.     // Uses the protocol combined with the endpoint for receiving RPC.
    52.     std::cout << "Initializing RPC server ..." << std::endl;
    53.     status = RpcServerUseProtseqEp(
    54.         reinterpret_cast<RPC_TSTR>(RPC_PROTOCOL), //  protocol.
    55.         RPC_C_PROTSEQ_MAX_REQS_DEFAULT, // Backlog queue .
    56.         reinterpret_cast<RPC_TSTR>(RPC_END_POINT), // endpoint.
    57.         NULL); // No security.
    58.  
    59.     if (status)
    60.         exit(status);
    61.  
    62.     std::cout << "Registering RPC server ..." << std::endl;
    63.     status = RpcServerRegisterIf2(
    64.         Hello_v1_0_s_ifspec, // Interface to register.
    65.         NULL,
    66.         NULL,
    67.         RPC_IF_ALLOW_CALLBACKS_WITH_NO_AUTH, // Forces use of security callback.
    68.         RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Use default number of concurrent calls.
    69.         (unsigned)-1, // Infinite max size of incoming data blocks.
    70.         SecurityCallback); // Naive security callback.
    71.  
    72.     if (status)
    73.         exit(status);
    74.  
    75.     // Start to listen for RPC.
    76.     std::cout << "Listen RPC server ..." << std::endl;
    77.     status = RpcServerListen(
    78.         1, // Recommended minimum number of threads.
    79.         RPC_C_LISTEN_MAX_CALLS_DEFAULT, // Recommended maximum number of threads.
    80.         TRUE); //dont wait
    81.  
    82.     // Start listening now. Wait for stop-message
    83.     WaitForSingleObject(hStopEvent, INFINITE);
    84.     Sleep(1000);
    85.  
    86.     RpcMgmtStopServerListening(Hello_v1_0_s_ifspec);
    87.     RpcServerUnregisterIf(Hello_v1_0_s_ifspec, NULL, 0);
    88.     CloseHandle(hStopEvent);
    89.     std::cout << "Server stopped." << std::endl;
    90.     if (status)
    91.         exit(status);
    92.     return 0;
    93. }
    94.  
    95. // Memory allocator
    96. void* __RPC_USER midl_user_allocate(size_t size)
    97. {
    98.     return malloc(size);
    99. }
    100.  
    101. void __RPC_USER midl_user_free(void* p)
    102. {
    103.     free(p);
    104. }
    Attached Files Attached Files

  9. #9
    Ngày gia nhập
    02 2014
    Nơi ở
    TP.HCM
    Bài viết
    904

    Đúng là quá cao nên đọc qua 3 lần vẫn chưa hiểu hết được. Trước mắt rút ra được 2 điều cơ bản :
    1. RPC vẫn đi theo xương sống của Windows ( cụ thể hơn là vẫn dùng định danh toàn cục - Có thể dùng CreateGuid Thay đổi mã mà Wizard tạo ra cho chúng ta)
    2. RPC có bố cục xử lý ngoại lệ riêng nằm ngoài các chỉ dẫn tiêu chuẩn của C++.

    Bạn có thể đi sâu hơn một chút nữa không. Thực sự là nhập và biên dịch chạy OK ( có sửa chút xíu) nhưng đúng là chưa gặp nên vẫn lúng túng nhiều ( do mình chỉ có 127.0.0.1).
    Đề tài này rất lý thú và hữu ích, mong bạn chia sẻ thêm. (Đương nhiên mình có tham khảo qua Gồ rồi, nhưng kinh nghiệm vẫn hơn lý thuyết).

  10. #10
    Ngày gia nhập
    11 2007
    Nơi ở
    Hà Nội
    Bài viết
    520

    Trích dẫn Nguyên bản được gửi bởi MHoang Xem bài viết
    Đúng là quá cao nên đọc qua 3 lần vẫn chưa hiểu hết được. Trước mắt rút ra được 2 điều cơ bản :
    1. RPC vẫn đi theo xương sống của Windows ( cụ thể hơn là vẫn dùng định danh toàn cục - Có thể dùng CreateGuid Thay đổi mã mà Wizard tạo ra cho chúng ta)
    2. RPC có bố cục xử lý ngoại lệ riêng nằm ngoài các chỉ dẫn tiêu chuẩn của C++.

    Bạn có thể đi sâu hơn một chút nữa không. Thực sự là nhập và biên dịch chạy OK ( có sửa chút xíu) nhưng đúng là chưa gặp nên vẫn lúng túng nhiều ( do mình chỉ có 127.0.0.1).
    Đề tài này rất lý thú và hữu ích, mong bạn chia sẻ thêm. (Đương nhiên mình có tham khảo qua Gồ rồi, nhưng kinh nghiệm vẫn hơn lý thuyết).
    Bạn có thể tìm hiểu về RPC ở MSDN, bài viết này mô tả khá chi tiết về nó: How RPC Works

    RPC là một mô hình được thiết kế và sử dụng từ lâu, với mục đích chính là tăng khả năng xử lý thông tin. Một chương trình đơn không thể xử lý toàn bộ dữ liệu, do đó, người ta nghĩ ra cách để xử lý dữ liệu phân tán. RPC là một trong những lời giải của bài toán này. Bằng cách dùng RPC, người ta có thể dựng những hệ thống tính toán song song.

    Việc liên lạc và chia sẻ dữ liệu chỉ là một trong những lợi ích của RPC. RPC định ra những kiểu dữ liệu chung để có thể chuyển đổi và đóng gói một cách dễ dàng. Nếu truyền một khối lớn dữ liệu, người ta thường dùng struct để đóng gói (serialization). Nhược điểm là khi de-serialization thì sẽ cần phải biết thứ tự, kích thước, cách alignment của struct. Đây là gánh nặng của lập trình viên, nhất là khi thay đổi rất nhỏ trong struct hay các tham số align lúc build chuơng trình. Với RPC, 2 chương trình không cần thiết phải biết được field nào ở offset bao nhiêu trong struct mà vẫn lấy được dữ liệu, giảm gánh nặng lập trình. Tất cả đều do RPC framework làm, trong suốt.

    Ngày nay, phần lớn các hệ thống ít dùng pipe (như ví dụ của mình ở trên) để thực hiện RPC. Ví dụ trên được viết vì mình thích lập trình trên Windows. Có những protocol tốt hơn nhiều được sử dụng trong RPC, ví dụ như network. Các framework tốt bây giờ đều dùng http-rpc ( tức là truyền dữ liệu thông qua http) và sử dụng một framework để serialization hiệu quả ( mình thích dùng protocol-buf framework hoặc Cap’n Proto ). Nếu truyền data giữa các chuơng trình với nhau trong máy tính, thì tốc độ của các kết nối local rất tốt, không lo chậm hơn so với pipe, ngoài ra, nếu lập trình trên linux thì có thể tận dụng Unix-socket để tăng hiệu năng.
    Công cụ bảo vệ mã nguồn .NET mạnh nhất hiện tại, miễn phí cho các khách hàng đầu tiên đăng ký.

Quyền hạn của bạn

  • Bạn không thể gửi đề tài mới
  • Bạn không thể gửi bài trả lời
  • Bạn không thể gửi các đính kèm
  • Bạn không thể chỉnh sửa bài viết của bạn