2014-10-25 21 views
16

Tôi đang cố gắng tạo ra một giao tiếp đơn giản giữa 2 quy trình trong C++ (Windows) như FIFO trong Linux. Đây là máy chủ của tôi:Tạo tên có đường ống C++ Windows

int main() 
{ 
    HANDLE pipe = CreateFile(TEXT("\\\\.\\pipe\\Pipe"), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); 
    ConnectNamedPipe(pipe, NULL); 
    while(TRUE){ 
     string data; 
     DWORD numRead =1 ; 
     ReadFile(pipe, &data, 1024, &numRead, NULL); 
     cout << data << endl; 

} 
    CloseHandle(pipe); 
    return 0; 
} 

Và đây là khách hàng của tôi:

int main() 
{ 
    HANDLE pipe = CreateFile(TEXT("\\\\.\\pipe\\Pipe"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); 
    ConnectNamedPipe(pipe, NULL); 
    string message = "TEST"; 
    DWORD numWritten; 
    WriteFile(pipe, message.c_str(), message.length(), &numWritten, NULL); 
    return 0; 
} 

Mã does't làm việc, làm thế nào tôi có thể cố định nó thích FIFO?

Trả lời

41

Bạn không thể tạo đường ống có tên bằng cách gọi CreateFile(..).

Hãy xem qua số pipe examples of the MSDN. Vì những ví dụ này khá phức tạp, tôi đã nhanh chóng viết một máy chủ và máy khách có tên là VERY.

int main(void) 
{ 
    HANDLE hPipe; 
    char buffer[1024]; 
    DWORD dwRead; 


    hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Pipe"), 
          PIPE_ACCESS_DUPLEX, 
          PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, // FILE_FLAG_FIRST_PIPE_INSTANCE is not needed but forces CreateNamedPipe(..) to fail if the pipe already exists... 
          1, 
          1024 * 16, 
          1024 * 16, 
          NMPWAIT_USE_DEFAULT_WAIT, 
          NULL); 
    while (hPipe != INVALID_HANDLE_VALUE) 
    { 
     if (ConnectNamedPipe(hPipe, NULL) != FALSE) // wait for someone to connect to the pipe 
     { 
      while (ReadFile(hPipe, buffer, sizeof(buffer) - 1, &dwRead, NULL) != FALSE) 
      { 
       /* add terminating zero */ 
       buffer[dwRead] = '\0'; 

       /* do something with data in buffer */ 
       printf("%s", buffer); 
      } 
     } 

     DisconnectNamedPipe(hPipe); 
    } 

    return 0; 
} 

Và đây là mã khách hàng:

int main(void) 
{ 
    HANDLE hPipe; 
    DWORD dwWritten; 


    hPipe = CreateFile(TEXT("\\\\.\\pipe\\Pipe"), 
         GENERIC_READ | GENERIC_WRITE, 
         0, 
         NULL, 
         OPEN_EXISTING, 
         0, 
         NULL); 
    if (hPipe != INVALID_HANDLE_VALUE) 
    { 
     WriteFile(hPipe, 
        "Hello Pipe\n", 
        12, // = length of string + terminating '\0' !!! 
        &dwWritten, 
        NULL); 

     CloseHandle(hPipe); 
    } 

    return (0); 
} 

Bạn nên thay thế tên của ống TEXT("\\\\.\\pipe\\Pipe") bởi một #define mà nằm trong một tập tin tiêu đề thường được sử dụng.

+1

Tôi đã nhận được lỗi trong đó 'FILE_FLAG_FIRST_PIPE_INSTANCE': 'FILE_FLAG_FIRST_PIPE_INSTANCE' không được khai báo trong phạm vi này nhưng tôi đã đọc trên msdn và nó không phải là bất kỳ lỗi nào ở đây. – user3052078

+0

sau khi khách hàng đầu tiên, máy chủ không đọc bất kỳ messsage khác, tại sao ông không thể vượt qua thorught đầu tiên nếu? – user3052078

+1

@ user3052078 Tôi đã thực hiện một số thay đổi và bây giờ nó hoạt động nếu khách hàng chạy một thời gian khác. Lưu ý thêm rằng nếu bạn đang gửi nhiều tin nhắn từ máy khách, máy chủ có thể đọc dữ liệu với một 'ReadFile (..)' (= 5x WriteFile của máy khách! = 5x ReadFile by server). Vì vậy, nếu các chuỗi được gửi bởi máy khách chứa các ký tự '\ 0' thì một 'printf ("% s ", bộ đệm) đơn giản,' như trong ví dụ này sẽ không hoạt động vì printf dừng ở đầu tiên '\ 0'. –

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