Segmentation fault in client/server implementation

Asked

Viewed 58 times

1

Hello, I’m implementing the game 21(Blackjack) in C++ in a Linux environment, During the execution it presents the error Segmentation fault, the problem is that I am not able to identify the error generator. The same appears after the first while loop happens. I’m running the code with netcat, it’s replacing my client. It even sends the data to the server for the first time and receives what the server sent and then presents the Segmentation fault. By the way I’m using socket.

#include <sstream>
#include <cstdlib>
#include <string>
#include <iostream>
#include <string.h>
#include <stdlib.h>             
#include <sys/socket.h>   // socket
#include <arpa/inet.h>    // inet_addr
#include <unistd.h>       // write

using namespace std;


int client_sock;
struct sockaddr_in server, client;
int socket_desc, c, read_size;
char client_message[1000];
int PORTA = 4000;
int totalj = 0;

void imprime(int sock, string m);
void processarCliente();
int criar_socket_server();
int randomInteger(int low, int high);
void limpa_Buffer();
void faz_Chamada(char variavel);
void processarPC();

/*
 * 
 */
int main() {
    int ok = 1;
    //imprime(0, "this is a test!!!");
    criar_socket_server();

    do {
        processarCliente();

    } while (ok);

    return 0;
}

void imprime(int sock, string m) {
    write(sock, m.c_str(), m.size()); //write n aceita string, logo tranformei em vetor de char
}

int criar_socket_server() {

    //Create socket
    socket_desc = socket(AF_INET, SOCK_STREAM, 0);
    if (socket_desc == -1) {
        cout << "Could not create socket\n";
    }
    cout << "Socket created\n";

    //Prepare the sockaddr_in structure
    server.sin_family = AF_INET; // IPv4
    server.sin_addr.s_addr = INADDR_ANY; // qualquer endereco
    server.sin_port = htons(PORTA); // porta a esperar por conexoes
    //Bind
    while (bind(socket_desc, (struct sockaddr *) &server, sizeof (server)) < 0) {//socket esc -> sockfd//server->local
        //print the error message
        PORTA++;
        cout << "Mundando para a porta " << PORTA << "\n";
        server.sin_port = htons(PORTA); // porta a esperar por conexoes
    }
    cout << "bind done\n";

    //Listen
    listen(socket_desc, 3);
}

void processarCliente() {
    int jogada = 0;
    totalj = 0;
    char temp;
    //Accept and incoming connection
    c = sizeof (struct sockaddr_in);

    //accept connection from an incoming client
    client_sock = accept(socket_desc, (struct sockaddr *) &client, (socklen_t*) & c);

    imprime(client_sock, "Bem Vindo ao BlackJack em C!!\n Você tem que fazer 21 pontos para ganhar, porém sem estourar esse limite, podendo parar após cada jogada.");


    //Receive a message from client
    while ((read_size = recv(client_sock, client_message, 1000, 0)) > 0) {


        if (client_message[0] == 's' || client_message[0] == 'S')//buffer -> client_mes
        {

            jogada = randomInteger(1, 10);
            totalj = (totalj + jogada);

            if (jogada == 10) {
                temp = '0';
            } else {
                temp = (char) jogada;
            }

            stringstream cc;
            cc << "\n O valor da sua carta eh  " << jogada << " e o seu total de pontos eh " << totalj;
            imprime(client_sock, cc.str()); //str transforma o fluxo de string em string

            if (totalj == 21) {
                imprime(client_sock, "Parabens! Você é o Vencedor! \n");
                close(client_sock);
                totalj = 0;
                break;
            } else if (totalj > 21) {
                stringstream cc;
                cc << "Que pena você perdeu! Os seus pontos estouraram!:\n " << totalj;
                imprime(client_sock, cc.str()); //str transforma o fluxo de string em string
                close(client_sock);
                totalj = 0;
                break;
            }

            faz_Chamada(temp);

            limpa_Buffer();

        } else if (client_message[0] == 'n' || client_message[0] == 'N') {
            stringstream cc;
            cc << "\n Total de pontos: " << totalj;
            imprime(client_sock, cc.str()); //str transforma o fluxo de string em string
            close(client_sock);
            totalj = 0;
            break;
        }

    }
}

int randomInteger(int low, int high) {
    int k;
    double d;
    srand(time(NULL));
    d = (double) rand() / ((double) RAND_MAX + 1);
    k = d * (high - low + 1);

    return low + k;
}

void limpa_Buffer() {
    int i;
    for (i = 0; i < 4096; i++) {
        client_message[i] = ' ';
    }
}

void faz_Chamada(char variavel) {
    cout << "fez chamada no cliente";

    char vet[1];

    vet[0] = variavel;

    limpa_Buffer();

    strcpy(client_message, vet);
    (send(client_sock, client_message, strlen(client_message), 0)); //cliente -> client_sock
    //    buffer[slen] = '\0';
    limpa_Buffer();

}
  • What are the steps to test your code?

1 answer

2


Simple. You allocate the variable client_message 1000-byte:

char client_message[1000];

But then, on the call from limpa_Buffer you make a loop up 4096:

for (i = 0; i < 4096; i++) {
    client_message[i] = ' ';
}

Hence, from the moment when i is worth 1000 or more, you are already invading unallocated memory area in that variable. Hence the segmentation error.

  • Thank you very much Luiz! .

  • For nothing Aline. However, next time this kind of error happens, remember to debug your program. The chances of the debugger stopping exactly on the line where the problem is.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.