2013-10-13 9 views
6

मेरे पास थ्रेड (पथ्रेड लाइब्रेरी) का उपयोग करके बहुआयामी के लिए चैट रूम करने के लिए एक सरल सर्वर और क्लाइंट सी कोड है। मेरी समस्या यह है कि मैं सर्वर को हर संदेश लिखने का एक तरीका नहीं सोच सकता जिसे क्लाइंट सॉकेट पर अन्य सभी ग्राहकों में भेजता है। मैंने यहां अन्य समान पदों को पढ़ा है और यह असहाय था। कृपया मेरी मदद करें मुझे स्कूल के लिए ऐसा करने की ज़रूरत है। मैं तुरंत दोनों कोड भेजूंगा।लिनक्स में सी/सॉकेट प्रोग्रामिंग में चैटरूम

Server.c:

#include<stdio.h> 
#include<string.h> //strlen 
#include<stdlib.h> //strlen 
#include<sys/socket.h> 
#include<arpa/inet.h> //inet_addr 
#include<unistd.h> //write 

#include<pthread.h> //for threading , link with lpthread 

void *connection_handler(void *); 


int main(int argc , char *argv[]) 
{ 
    int socket_desc , new_socket , c , *new_sock; 
    struct sockaddr_in server , client; 
    char *message; 

    //Create socket 
    socket_desc = socket(AF_INET , SOCK_STREAM , 0); 
    if (socket_desc == -1) 
    { 
     printf("Could not create socket"); 
    } 

    //Prepare the sockaddr_in structure 
    server.sin_family = AF_INET; 
    server.sin_addr.s_addr = INADDR_ANY; 
    server.sin_port = htons(8888); 

    //Bind 
    if(bind(socket_desc,(struct sockaddr *)&server , sizeof(server)) < 0) 
    { 
     puts("bind failed"); 
     return 1; 
    } 
    puts("bind done"); 

    //Listen 
    listen(socket_desc , 3); 

    //Accept and incoming connection 
    puts("Waiting for incoming connections..."); 
    c = sizeof(struct sockaddr_in); 
    while((new_socket = accept(socket_desc, (struct sockaddr *)&client, (socklen_t*)&c))) 
    { 
     puts("Connection accepted"); 

     pthread_t sniffer_thread; 
     new_sock = malloc(1); 
     *new_sock = new_socket; 

     if(pthread_create(&sniffer_thread , NULL , connection_handler , (void*) new_sock) < 0) 
     { 
      perror("could not create thread"); 
      return 1; 
     } 

     //Now join the thread , so that we dont terminate before the thread 
     //pthread_join(sniffer_thread , NULL); 
     puts("Handler assigned"); 
    } 

    if (new_socket<0) 
    { 
     perror("accept failed"); 
     return 1; 
    } 

    return 0; 
} 

/* 
* This will handle connection for each client 
* */ 
void *connection_handler(void *socket_desc) 
{ 
    //Get the socket descriptor 
    int sock = *(int*)socket_desc; 
    int read_size; 
    char *message , client_message[2000]; 


    //Receive a message from client 
    while((read_size = recv(sock , client_message , 2000 , 0)) > 0) 
    { 
     //Send the message back to client 
     write(sock , client_message , strlen(client_message)); 
    } 

    if(read_size == 0) 
    { 
     puts("Client disconnected"); 
     fflush(stdout); 
    } 
    else if(read_size == -1) 
    { 
     perror("recv failed"); 
    } 

    //Free the socket pointer 
    free(socket_desc); 

    return 0; 
} 

Client.c

#include<stdio.h> //printf 
#include<string.h> //strlen 
#include<sys/socket.h> //socket 
#include<arpa/inet.h> //inet_addr 

int main(int argc , char *argv[]) 
{ 
    int sock; 
    struct sockaddr_in server; 
    char message[1000] , server_reply[2000]; 

    //Create socket 
    sock = socket(AF_INET , SOCK_STREAM , 0); 
    if (sock == -1) 
    { 
     printf("Could not create socket"); 
    } 
    puts("Socket created"); 

    server.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    server.sin_family = AF_INET; 
    server.sin_port = htons(8888); 

    //Connect to remote server 
    if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0) 
    { 
     perror("connect failed. Error"); 
     return 1; 
    } 

    puts("Connected\n"); 
    puts("Bienvenido al Chatroom, puedes empezar a escribir en la sala!"); 

    //keep communicating with server 
    while(1) 
    { 

     printf("Enter message: "); 
    fgets(message, sizeof(message),stdin); 
     //scanf("%s" , message); 

     //Send some data 
     if(send(sock , message , strlen(message) , 0) < 0) 
     { 
      puts("Send failed"); 
      return 1; 
     } 

     //Receive a reply from the server 
     if(recv(sock , server_reply , 2000 , 0) < 0) 
     { 
      puts("recv failed"); 
      break; 
     } 

    printf("Server Reply: %s\n", server_reply); 
    server_reply[0]='\0'; 
    } 

    close(sock); 
    return 0; 
} 

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

मैं जानता हूँ कि यह लंबा है किसी को भी देखभाल करने के लिए के लिए है, लेकिन अगर आप कर सकते हैं, मैं कुछ मदद :)

+0

क्या आपके लिए इसके लिए धागे का उपयोग करना आवश्यक है? एक आसान डिज़ाइन एकल-थ्रेडेड होगा और चयन() या मतदान() का उपयोग करके I/O संचालन को मल्टीप्लेक्स करेगा। फिर सभी क्लाइंट के सॉकेट को लिखना एक साधारण फॉर-लूप का उपयोग करके किया जा सकता है। –

+0

ओह धन्यवाद कि शायद आसान हो जाएगा। फिर भी, मुझे नहीं पता कि चयन() या मतदान() हाहा का उपयोग कैसे करें। मैंने धागे का इस्तेमाल किया क्योंकि हाल ही में मैंने उन्हें सीखने का तरीका सीखा और वे मेरी समस्या हाहा के लिए काफी समर्थक समाधान लग रहे थे। कोई भी मौका आप मुझे उन कार्यों में से किसी एक का उपयोग करने के बारे में थोड़ा विस्तार दे सकते हैं? :) –

+0

धागे मजबूत दवा हैं - वे आपको तब तक काट सकते हैं जब तक आप बहुत सावधान न हों। मैं उनका उपयोग करने की कोशिश नहीं करता जब तक कि कार्य को पूरा करने का कोई और तरीका न हो। चुनिंदा() के लिए, इन लिंक को देखें: http://www.lowtek.com/sockets/select.html http://www.binarytides.com/multiple-socket-connections-fdset-select-linux/ –

उत्तर

5

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

जब कोई ग्राहक संदेश भेजता है, तो वैश्विक तालिका पर लॉक प्राप्त करें और इसे पार करें। सभी क्लाइंट को संदेश भेजें (संदेश भेजने वाले किसी अन्य के अलावा, यदि आप किसी संदेश को अपने स्रोत पर प्रतिबिंबित नहीं करना चाहते हैं)।

यह वास्तविक सर्वर यह कैसे करता है इसका सकल ओवरम्प्लिफिकेशन है। लेकिन यह आपको शुरू करने के लिए पर्याप्त होना चाहिए।

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