2011-12-23 10 views
6

Tôi đang cố gắng viết các chương trình C máy khách và máy khách đơn giản, giao tiếp với nhau trong các đầu cuối riêng biệt.Kết nối máy khách-máy chủ FIFO thích hợp

Máy chủ phải tạo công khai năm mươi và chờ khách hàng. Trong khi đó khách hàng đang tạo ra FIFO của riêng mình thông qua phản hồi của máy chủ sẽ đến. Nhiệm vụ của máy khách gửi cho máy chủ một tên được tạo bởi hàng đợi và lấy lại kết quả của lệnh ls.

Tôi đã tìm kiếm câu trả lời, ví dụ: fifo-server-program, example-of-using-named-pipes-in-linux-bash, how-to-send-a-simple-string-between-two-programs-using-pipes. Tôi bắt đầu với mã từ liên kết thứ ba và từ từ sửa đổi nó.

Điều tôi hiện có, là một ứng dụng khách lấy dữ liệu đầu vào từ người dùng, gửi nó đến máy chủ và nhận lại. Nhưng nó chỉ hoạt động một lần. Tôi không biết tại sao. Phần thân của hàm chính bên dưới. Tôi sẽ biết ơn vì sự giúp đỡ nào.

EDIT: Tôi hiểu nó hoạt động! : D Các mã dưới đây, có thể nó sẽ giúp một ai đó.

Mã server.c:

#include <unistd.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 

int main(int argc, char* argv[]) 
{ 
    int fds[2]; 
    char tab[BUFSIZ]; 
    int fd, n; 

    char *myfifo = "/tmp/serwer"; 
    char *myfifo2 = "/tmp/client"; 

    pipe(fds); 
    mkfifo(myfifo,0666); 

    while(1) 
    { 
     fds[0]=open(myfifo2,O_RDONLY); 
     fds[1]=open(myfifo,O_WRONLY); 

     read(fds[0],tab,BUFSIZ); 

     if (strcmp("klient",tab)==0) { 
      printf("Od klienta: %s\n",tab); 
      fd=open(tab,O_WRONLY); 

      if(fork()==0) 
      { 
       dup2(fds[1],1); 
       close(fds[1]); 
       execlp("ls","ls","-l",NULL); 
       close(fds[0]); 
       close(fds[1]); 
      } 
      else 
      { 
       dup2(fds[0],0); 
       n = read(fds[0],tab,BUFSIZ); 
       write(fd,tab,n); 
       close(fds[0]); 
       close(fds[1]); 
      } 
     } 
     memset(tab, 0, sizeof(tab)); 
     close(fd); 
     close(fds[0]); 
     close(fds[1]); 
    } 

    unlink(myfifo); 
    return 0; 
} 

Mã client.c:

#include <unistd.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <string.h> 

int main(int argc, char* argv[]) 
{ 
    int fds[2]; 
    char *myfifo = "/tmp/serwer"; 
    char *myfifo2 = "/tmp/client"; 

    mkfifo(myfifo2,0666); 
    fds[0]=open(myfifo,O_RDONLY); 
    fds[1]=open(myfifo2,O_WRONLY); 

    char tab[BUFSIZ]; 
    memset(tab, 0, sizeof(tab)); 

    write(fds[1],"klient",6); 
    perror("Write:"); //Very crude error check 
    read(fds[0],tab,sizeof(tab)); 
    perror("Read:"); // Very crude error check 

    printf("Odebrano od serwera: %s\n",tab); 

    close(fds[0]); 
    close(fds[1]); 
    unlink(myfifo2); 
    return 0; 
} 
+1

Không rõ ràng từ mã này. Bạn đã nhận được đầu ra ls làm việc hay bạn chỉ gửi tin nhắn nhỏ? Lỗ hổng thông thường trong trường hợp này là bạn bế tắc tức là máy chủ đang đợi đầu vào trong khi máy khách đang đợi đầu vào. Họ chờ đợi mãi mãi bởi vì không ai gửi bất cứ điều gì. – Duck

+0

Không, lệnh ls vẫn chưa hoạt động. Các chương trình này hoạt động một lần - máy chủ đợi một tin nhắn, trả về cho máy khách, máy khách có thể đóng. Khi tôi muốn gửi một tin nhắn khác, cả máy khách và máy chủ đều không phản hồi. – uluroki

Trả lời

5

Tại sao bạn không chỉ quản lý cả của fifo trong máy chủ? Chỉ cần thay đổi mã của bạn để làm điều này làm cho nó hoạt động chính xác.

Nếu bạn thực sự muốn có một mối quan hệ khách hàng-máy chủ, với một máy chủ phục vụ nhiều khách hàng khác nhau, ổ cắm có lẽ sẽ là một lựa chọn tốt hơn.

client.cpp

#include <stdio.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
#include <sys/types.h> 
#include <unistd.h> 

int main() 
{ 
    int client_to_server; 
    char *myfifo = "/tmp/client_to_server_fifo"; 

    int server_to_client; 
    char *myfifo2 = "/tmp/server_to_client_fifo"; 

    char str[BUFSIZ]; 
    printf("Input message to serwer: "); 
    scanf("%s", str); 


    /* write str to the FIFO */ 
    client_to_server = open(myfifo, O_WRONLY); 
    server_to_client = open(myfifo2, O_RDONLY); 
    write(client_to_server, str, sizeof(str)); 

    perror("Write:"); //Very crude error check 

    read(server_to_client,str,sizeof(str)); 

    perror("Read:"); // Very crude error check 

    printf("...received from the server: %s\n",str); 
    close(client_to_server); 
    close(server_to_client); 

    /* remove the FIFO */ 

    return 0; 
} 

server.cpp

#include <fcntl.h> 
#include <stdio.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <string.h> 

int main() 
{ 
    int client_to_server; 
    char *myfifo = "/tmp/client_to_server_fifo"; 

    int server_to_client; 
    char *myfifo2 = "/tmp/server_to_client_fifo"; 

    char buf[BUFSIZ]; 

    /* create the FIFO (named pipe) */ 
    mkfifo(myfifo, 0666); 
    mkfifo(myfifo2, 0666); 

    /* open, read, and display the message from the FIFO */ 
    client_to_server = open(myfifo, O_RDONLY); 
    server_to_client = open(myfifo2, O_WRONLY); 

    printf("Server ON.\n"); 

    while (1) 
    { 
     read(client_to_server, buf, BUFSIZ); 

     if (strcmp("exit",buf)==0) 
     { 
     printf("Server OFF.\n"); 
     break; 
     } 

     else if (strcmp("",buf)!=0) 
     { 
     printf("Received: %s\n", buf); 
     printf("Sending back...\n"); 
     write(server_to_client,buf,BUFSIZ); 
     } 

     /* clean buf from any data */ 
     memset(buf, 0, sizeof(buf)); 
    } 

    close(client_to_server); 
    close(server_to_client); 

    unlink(myfifo); 
    unlink(myfifo2); 
    return 0; 
} 
4

Nó chỉ hoạt động một lần vì cách đặt tên đường ống làm việc. Mỗi lần bạn open một đường ống được đặt tên để đọc, bạn chặn cho đến khi một quy trình khác mở nó để ghi. Sau đó, bạn đã ghép nối và trình mô tả tệp kết nối các quy trình của bạn. Khi một trong hai đầu kết thúc, kết nối đó là kết thúc của đường ống đó. Để máy chủ của bạn "chấp nhận một kết nối khác", nó cần di chuyển các đường ống chính của openclose để nó có thể được ghép nối nhiều lần.