2011-12-23 14 views
6

मैं सरल क्लाइंट और सर्वर सी प्रोग्राम लिखने की कोशिश कर रहा हूं, अलग-अलग टर्मिनलों में एक दूसरे के साथ संवाद कर रहा हूं।उचित फीफो क्लाइंट-सर्वर कनेक्शन

सर्वर को सार्वजनिक फीफो बनाना है और ग्राहक के लिए प्रतीक्षा करना है। इस बीच ग्राहक अपना खुद का फीफो बना रहा है जिसके माध्यम से सर्वर की प्रतिक्रिया आ जाएगी। क्लाइंट का कार्य सर्वर को कतार द्वारा बनाया गया नाम भेज रहा है और ls कमांड के परिणाम को वापस लौटा रहा है।

मैंने एक उत्तर खोजा, उदाहरण के लिए: fifo-server-program, example-of-using-named-pipes-in-linux-bash, how-to-send-a-simple-string-between-two-programs-using-pipes। मैंने तीसरे लिंक से कोड के साथ शुरू किया और धीरे-धीरे इसे संशोधित किया।

अब मुझे जो मिला है, वह क्लाइंट उपयोगकर्ता से इनपुट ले रहा है, इसे सर्वर पर भेज रहा है और इसे वापस प्राप्त कर रहा है। लेकिन यह केवल एक बार काम करता है। मुझे कोई जानकारी नहीं है की क्यों। मुख्य कार्य का शरीर नीचे है। मैं किसी भी मदद के लिए आभारी रहूंगा।

संपादित करें: मैं यह काम कर रहा हो गया है! : डी कोड नीचे हैं, शायद यह किसी की मदद करेगा।

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; 
} 

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

यह इस कोड से स्पष्ट नहीं है। क्या आप एलएस आउटपुट काम कर रहे हैं या आप बस छोटे संदेश भेज रहे हैं? इस परिदृश्य में सामान्य गड़बड़ यह है कि आप डेडलॉक i.e. सर्वर इनपुट के लिए इंतजार कर रहा है जबकि ग्राहक इनपुट के लिए इंतजार कर रहा है। वे हमेशा के लिए इंतजार करते हैं क्योंकि कोई भी कुछ भेज रहा है। – Duck

+0

नहीं, ls कमांड अभी तक काम नहीं कर रहा है। ये प्रोग्राम एक बार काम करते हैं - सर्वर एक संदेश के लिए इंतजार कर रहा है, इसे क्लाइंट को वापस कर देता है, ग्राहक बंद कर सकता है। जब मैं एक और संदेश भेजना चाहता हूं, तो ग्राहक और सर्वर दोनों उत्तरदायी नहीं बनते हैं। – uluroki

उत्तर

5

आप क्यों नहीं बस दोनों फीफो का प्रबंधन नहीं करते सर्वर में? ऐसा करने के लिए बस अपना कोड बदलना यह सही ढंग से काम करता है।

यदि आप वास्तव में क्लाइंट-सर्वर संबंध रखना चाहते हैं, तो कई अलग-अलग ग्राहकों की सेवा करने वाले सर्वर के साथ, सॉकेट शायद बेहतर विकल्प होगा।

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

यह केवल क्योंकि कैसे नामित पाइप काम का एक बार काम करता है। प्रत्येक बार जब आप open पढ़ने के लिए नामित पाइप को ब्लॉक करते हैं तब तक एक और प्रक्रिया इसे लिखने के लिए खुलती है। फिर आप को जोड़ा जाता है और फ़ाइल डिस्क्रिप्टर आपकी प्रक्रियाओं को जोड़ता है। एक बार या तो अंत उस कनेक्शन को बंद कर देता है जो उस पाइप का अंत होता है। अपने सर्वर को "किसी अन्य कनेक्शन को स्वीकार करने" के लिए, इसे पाइपों के open और close को अपने मुख्य पाश में स्थानांतरित करने की आवश्यकता है ताकि इसे ऊपर और ऊपर जोड़ा जा सके।

संबंधित मुद्दे