lundi 1 janvier 2018

Multiple connections sockets c++

I'm trying to implement my own server and client side which uses sockets to send and receive data. But i got some problem with realization of multi-threading. My server.cpp:

#include <iostream>
#include <netinet/in.h>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
#include <thread>
#include <vector>
#include <string>
using namespace std;

void connection_handler(int* socket) {
    char client_message[256];
    memset(&client_message, 0, 256);
    size_t message_size = 0;

    while ((message_size = recv(*socket, client_message, 256, 0)) > 0) {
        client_message[message_size] = '\0';
        cout << "[Server] Client message accepted" << endl;
        cout << "[Server] Client message: " << client_message << endl;

        if (write(*socket, client_message, message_size) == -1) {
            cout << "[Client] Message sending failed" << endl;
            return;
        }
        cout << "[Server] Message sent to client" << endl << endl;
        cout << "============================" << endl << endl;
        cout.flush();

        memset(&client_message, 0, 256);
    }
}

int main() {
    unsigned short int PORT = 8080;
    int sockfd, listener, client_socket;
    socklen_t client_len;

    struct sockaddr_in server_address{};

    memset(&server_address, 0, sizeof(server_address));

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    listener = socket(AF_INET, SOCK_STREAM, 0);

    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(PORT);
    if (inet_aton("127.0.0.1", &server_address.sin_addr) == 0) {
        cout << "[Server] Invalid IP address" << endl;
        return -1;
    }

    if (bind(listener, (struct sockaddr*) &server_address, sizeof(server_address)) == -1) {
        cout << "[Server] Binding failed" << endl;
        return -1;
    }
    cout << "[Server] All setting are done" << endl;
    cout << "[Server] Server enabled" << endl;

    if (listen(listener, 100) == -1) {
        cout << "[Server] Listening failed" << endl;
        return -1;
    }
    cout << "[Server] Waiting for connection..." << endl;

    vector<unique_ptr<thread>> threads;

    for (; ;) {
        client_socket = accept(listener, (struct sockaddr*) &server_address, &client_len);
        cout << "[Server] Connection accepted" << endl << endl;
        cout << "----------------------------" << endl << endl;

        int new_socket = client_socket;

        thread handling_thread(connection_handler, &new_socket);
        handling_thread.detach();
    }
}

My client.cpp:

#include <iostream>
#include <netinet/in.h>
#include <cstring>
#include <arpa/inet.h>
#include <unistd.h>
using namespace std;

int main() {
    unsigned short int PORT = 8080;
    int sockfd;
    char buffer[256] = {0};
    struct sockaddr_in server_address{};

    sockfd = socket(AF_INET, SOCK_STREAM, 0);

    memset(&server_address, '0', sizeof(server_address));
    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(PORT);
    server_address.sin_addr.s_addr = INADDR_ANY;

    if (connect(sockfd, (struct sockaddr*) &server_address, sizeof(server_address)) < 0) {
        cout << "[Client] Connection failed" << endl;
        return -1;
    }
    cout << "[Client] All setting are done" << endl;
    cout << "[Client] Succefully connected to server" << endl << endl;
    cout << "----------------------------" << endl << endl;

    while (true) {
        string client_request;
        cout << "[Client] Enter a message: ";
        getline(cin, client_request);

        if (client_request == "-1") {
            write(sockfd, client_request.c_str(), client_request.size());
            close(sockfd);
            cout << endl << "[Client] Client exited" << endl;
            return 0;
        }

        if (write(sockfd, client_request.c_str(), client_request.size()) == -1) {
            cout << "[Client] Message sending failed" << endl;
        }
        cout << "[Client] Message sent to server" << endl;

        memset(&buffer, 0, 256);
        read(sockfd, buffer, 256);

        cout << "[Client] Server message: " << buffer << endl << endl;
        cout << "============================" << endl << endl;
        cout.flush();
    }
}

It's perfectly working until i create one more connection to server and after that second client cans send and receive data, but first one at this time becomes not working. I compiled my program like this: g++ server.cpp -lpthread -o server -std=c++11 And then in other console tab run my compiled client.cpp: ./client. To check multi-threading working i run client one more time (in other tab again) and trying send requests in two tabs at the same time. I want to realize multi-threading in my program. How can i do this?

Aucun commentaire:

Enregistrer un commentaire