मैं एक सर्वर बनाने की कोशिश कर रहा हूं जो एकाधिक कनेक्टेड क्लाइंट से संदेश प्राप्त कर सकता है, लेकिन मेरे कोड में, आरईवी() फ़ंक्शन हमेशा -1 लौटाता है। मैं अपने सर्वर को क्लाइंट से कोड कैसे प्राप्त कर सकता हूं?

यह मेरा सर्वर है। recv () फ़ंक्शन को नीचे लूप में कहा जाता है।

मैंने रीड() का उपयोग करने की कोशिश की, लेकिन मुझे इसे अनब्लॉक करने का कोई तरीका नहीं मिला। क्या रीड() का उपयोग करके इसकी व्याख्या करने का कोई तरीका है? यदि नहीं, तो मैं इस समस्या को कैसे ठीक कर सकता हूं recv() हमेशा -1 लौट रहा है, इसके बावजूद कि मेरे पास एक नया क्लाइंट जुड़ा हुआ है और एक नया संदेश भेजा गया है?

    /*------------------Header Files----------------------------------------------------------------------*/
#define _GNU_SOURCE

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<errno.h>
#include<fcntl.h>

#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<sys/stat.h>

#include<netinet/in.h>
#include<netinet/ip.h>

#include<arpa/inet.h>

/*-------------------Linked List------------------------------------------------------------------------*/
struct client_online{

        int client_socket;
        char* name;
        struct client_online* next;
};

/*-------------------Global Variables-------------------------------------------------------------------*/
struct client_online* first_client = NULL;

/*-------------------Main Function----------------------------------------------------------------------*/
int main(int argc, char* argv[]){

    // Cite: get help from office hour code
    // Creating the socket
    int server_socket;
    server_socket = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, 0);
    if(server_socket < 0){
        perror("Error creating server socket");
        return -1;
    }

    // Server address
    struct sockaddr_in server_address;
    memset(&server_address, 0, sizeof(struct sockaddr_in));
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(atoi(argv[2]));
    server_address.sin_addr.s_addr = inet_addr(argv[1]);

    // Binding the socket
    int binder = bind(server_socket, (const struct sockaddr *) &server_address, sizeof(server_address));
    if(binder == -1){
            perror("Error calling bind");
            return -1;
    }

    // Listen to the socket
    int listener = listen(server_socket, 50);
    if(listener == -1){
            perror("Error calling listen");
            return -1;
    }

    // Client address
    struct sockaddr_in client_address;

    // Reading and writing
    int quit = 0;
    while(!quit){

        // Check if there is a new connection
        int client_address_size = sizeof(client_address);
        int each_client_socket = accept4(server_socket,
                     (struct sockaddr*) &client_address,
                         &client_address_size,
                     SOCK_NONBLOCK);

        // If there is a new connection, add client to linked list
        if(each_client_socket >= 0){

            if(first_client == NULL){
                first_client = malloc(sizeof(*first_client));
                first_client->client_socket = each_client_socket;
                first_client->name = (char*)malloc(100);
                strcpy(first_client->name,"User");
                first_client->next = NULL;

                free(first_client->name);
                free(first_client);
            }

            else{
                struct client_online* tracker = first_client;
                while(tracker->next != NULL){
                    tracker = tracker->next;
                }

                struct client_online* new_client;
                new_client = malloc(sizeof(*new_client));
                new_client->client_socket = each_client_socket;

                new_client->name = (char*)malloc(100);
                strcpy(new_client->name, "User");
                new_client->next = NULL;
                tracker->next = new_client;

                free(new_client->name);
                free(new_client);
            }
        }

        // Check if there are messages recieved
        struct client_online* checker = first_client;
        while(checker != NULL){

            char client_response[256];
            char toSend[256];

            bzero(client_response, sizeof(client_response));

            int receiver = recv(checker->client_socket,
                                client_response,
                                sizeof(client_response),
                                MSG_DONTWAIT);

            printf("%d\n", receiver);
            if(receiver > 0){
                printf("message received\n");
                snprintf(toSend, sizeof(toSend), "%s: %s\n", checker->name, client_response);

                struct client_online* sender = first_client;
                while(sender != NULL){

                    send(sender->client_socket, toSend, sizeof(toSend), MSG_DONTWAIT);
                }
            }

            checker = checker->next;
        }

        sleep(1);

    }

        return 0;
}

यहाँ मेरा ग्राहक है

/*----------------------------------------------------Header Files----------------------------------------*/
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<unistd.h>

#include<fcntl.h>

#include<sys/types.h>
#include<sys/socket.h>
#include<sys/un.h>
#include<sys/stat.h>

#include<netinet/ip.h>
#include<arpa/inet.h>

#define _GNU_SOURCE
/*----------------------------------------------------Main Function--------------------------------------*/
int main(int argc, char* argv[]){

    // Seek help from office hour codes
    // Create the client socket
    int client_socket = socket(AF_INET, SOCK_STREAM, 0);
    if(client_socket < 0){
        perror("Error creating client socket");
        return -1;
    }

    // Construct the address of the connection
    struct sockaddr_in client_address;
    memset(&client_address, 0, sizeof(struct sockaddr_in));
    client_address.sin_family = AF_INET;
    client_address.sin_port = htons(atoi(argv[2]));
    client_address.sin_addr.s_addr = inet_addr(argv[1]);

    // Connect the client to the server
    int connecter = connect(client_socket,
                    (const struct sockaddr*) &client_address,
                    sizeof(struct sockaddr_in));
    if(connecter < 0){
        perror("Error connecting to server");
    }

    // Reading and writing
    int quit = 0;
    while(!quit){

        // Read from command line
        char client_message[256];
        memset(&client_message, 0, sizeof(client_message));

        int flags = fcntl(STDIN_FILENO, F_GETFL, 0);
        fcntl(STDIN_FILENO, F_SETFL, flags | O_NONBLOCK);
        int reader = read(STDIN_FILENO, client_message, sizeof(client_message));

        if (reader > 0) {

            // Writing normal message
            send(client_socket, client_message, 1, MSG_WAITALL);
        }
        //
        sleep(1);

    }

    return 0;
}
c
0
NNNNNNN 7 पद 2019, 13:02
क्या errno, EAGAIN के बराबर है, जब recv, -1 लौटाता है?
 – 
jxh
7 पद 2019, 13:05
हाँ, ग़लती == EAGAIN || त्रुटि == ईवॉल्डब्लॉक
 – 
NNNNNNN
7 पद 2019, 13:08
फिर आपको बस निर्देशों को पढ़ने की जरूरत है। किसी भी मामले में, यदि आप अपने कोड से न्यूनतम प्रतिलिपि प्रस्तुत करने योग्य उदाहरण निकालते हैं तो यह वास्तव में मदद करेगा। जब बड़े हिस्से वैसे भी अप्रासंगिक हों तो अपना पूरा कोड यहां डंप करने की कोई आवश्यकता नहीं है। यहां एक नए उपयोगकर्ता के रूप में, कृपया दौरे में भी शामिल हों और कैसे पूछें
 – 
Ulrich Eckhardt
7 पद 2019, 13:14

1 उत्तर

सबसे बढ़िया उत्तर

चूंकि आप अपने recv कॉल को MSG_DONTWAIT पास कर रहे हैं, अगर क्लाइंट से अभी तक प्राप्त करने के लिए कुछ भी नहीं है, तो कॉल उस तथ्य को इंगित करने के लिए एक त्रुटि लौटाएगा।

यदि आप मतदान तंत्र का उपयोग कर रहे हैं, जैसे epoll, तो आप आमतौर पर एक पठनीय अधिसूचना की प्रतीक्षा करेंगे। सूचना प्राप्त होने के बाद, आप recv कॉल का पुन: प्रयास कर सकते हैं। मुझे आपके कोड में मतदान तंत्र का कोई उपयोग नहीं दिख रहा है।

वैकल्पिक रूप से, आप प्रत्येक नए कनेक्शन के लिए एक थ्रेड स्पॉन कर सकते हैं, और recv (MSG_DONTWAIT ध्वज को छोड़ दें) के लिए ब्लॉकिंग कॉल का उपयोग कर सकते हैं।

0
jxh 7 पद 2019, 13:15