I'm trying to build a game where a client gets to play against a server in a game of Tic Tac Toe. I've built the game and followed a somehow structured design of how the game is supposed to happen, with the client and the server exchanging messages, but they seem to lose synchronisation at the beginning of the game. The server sends a GOO message, which is supposed to start the game, but it seems the client never receives it. The server doesn't even care about that and just goes on, reaching a point where both ends expect a message in return but if one of them gives a message, the run fails because of the error detection I've put in place.Here are both codes, I would be really glad if you could help me out, I'm really new to all the socket programming stuff.Here is the server side:#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/wait.h>#include <signal.h>#define MYPORT 5555    // Le port ou se connectent les utilisateurs#define BACKLOG 10 // Le nombre de connections accepteesint sockfd, new_fd;          // listen on sock_fd, new connection on new_fdstruct sockaddr_in my_addr;      // my address informationstruct sockaddr_in their_addr;      // connector's address informationunsigned int sin_size;//-------------------------------- Le Serveur ----------------------------------int setup_listener(){    printf(\nsetup_listener\n);    // Socket que l'on va listen.    sockfd = socket(PF_INET, SOCK_STREAM, 0);    if (sockfd < 0)    {        perror(Erreur a l'ouverture du socket 'listener'.);        exit(EXIT_FAILURE);    }    // Mise a 0 de la memoire pour le serveur.    memset(&my_addr, 0, sizeof(my_addr));    // Set up des infos du serveur    my_addr.sin_family = AF_INET;       my_addr.sin_addr.s_addr = INADDR_ANY;       my_addr.sin_port = htons(MYPORT);           // Bind des infos du serveur au socket.    if (bind(sockfd, (struct sockaddr *) &my_addr,             sizeof(my_addr)) < 0)    {        perror(Erreur au binding du socket 'listener'.);        exit(EXIT_FAILURE);    }}void get_client(){    printf(\nget_client\n);    if (listen(sockfd, BACKLOG) < 0)    {        perror(Erreur lors du listen.);        exit(EXIT_FAILURE);    }    sin_size = sizeof(struct sockaddr_in);    // Mise a zero de la memoire pour le client.    memset(&their_addr, 0, sin_size);    new_fd = accept (sockfd, (struct sockaddr *)&their_addr, &sin_size);    if (new_fd < 0)    {        perror(Erreur lors de l'accept.);        exit(EXIT_FAILURE);    }    printf(Serveur:  connection recue du client %s\n,     inet_ntoa(their_addr.sin_addr));}//---------------------------------- Le Jeu ------------------------------------void write_client_int(int msg){    printf(\nwrite_client_int\n);    int n = write(new_fd, &msg, sizeof(int));    if (n < 0)    {        perror(Erreur lors de l'ecriture d'entier.);        exit(EXIT_FAILURE);    }}void write_client_msg(char * msg){    printf(\nwrite_client_msg\n);    int n = write(new_fd, msg, strlen(msg));    if (n < 0)    {        perror(Erreur lors de la transmission de message);        exit(EXIT_FAILURE);    }}int recv_int(){    printf(\nrecv_int\n);    int msg = 0;    int n = read(new_fd, &msg, sizeof(int));    if (n < 0 || n != sizeof(int))        {        perror(Erreur lors de la reception de message(int).);        exit(EXIT_FAILURE);        }    return msg;}int get_player_move(){     printf(\nget_player_move\n);    write_client_msg(TRC);    // Demande ce que le joueur veut faire.    return recv_int();}int check_move(char board[3][3], int move){    printf(\ncheck_move\n);    if ((move == 9) || (board[move/3][move%3] == ' '))       return 1;   else        return 0;}void update_board(char board[3][3], int move){    printf(\nupdate_board\n);    board[move/3][move%3] = 'X';}void send_update(int move){    printf(\nsend_update\n);    write_client_msg(MAJ);    // Envoie le resultat apres un placement de morpion.    write_client_int(move); }int check_board(char board[3][3], int last_move){    printf(\ncheck_board\n);    int row = last_move/3;    int col = last_move%3;    if ( board[row][0] == board[row][1] && board[row][1] == board[row][2])     {        // Si victoire atteinte sur une ligne.        if (board[row][0] == 'X')            return 1;        else if (board[row][0] == 'O')            return 2;    }    else if ( board[0][col] == board[1][col] && board[1][col] == board[2][col] )     {        // Si victoire atteinte sur une colonne.        if (board[0][col] == 'X')            return 1;        else if (board[0][col] == 'O')            return 2;    }    else if ( (last_move == 0 || last_move == 4 || last_move == 8) &&         (board[1][1] == board[0][0] && board[1][1] == board[2][2]) )    {        // Si victoire atteinte sur la diagonale descendante.        if (board[1][1] == 'X')            return 1;        else if (board[1][1] == 'O')            return 2;    }    else if ( (last_move == 2 || last_move == 4 || last_move == 6) &&         (board[1][1] == board[0][2] && board[1][1] == board[2][0]) )    {        // Si victoire atteinte sur la diagonale montante.        if (board[1][1] == 'X')            return 1;        else if (board[1][1] == 'O')            return 2;    }    return 0;}void server_play(char board[3][3]){    printf(\nserver_play\n);    int random_move;    do    {        random_move = rand()%8;        if (check_move(board, random_move) == 1)        {            update_board(board, random_move);        }    }    while (!check_move(board, random_move));}void Play_game(){    printf(\nPlay_game\n);    printf(Writing message to client GOO. 0);    char board[3][3] = { {' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '} };    int game_over = 0;    int turns = 0;    printf(Writing message to client GOO. 1);    write_client_msg(GOO);    printf(Writing message to client GOO. 2);    while (game_over == 0)    {        int valid_move = 0;        int move = 0;        while (!valid_move)        {            move = get_player_move();            if (move < 0)            {                perror(Erreur lors de la reception du placement indique.);                exit(EXIT_FAILURE);            }            valid_move = check_move(board, move);        }        update_board(board, move);        game_over = check_board(board, move);        send_update(move);        if (game_over == 0)            server_play(board);        send_update(move);        game_over = check_board(board, move);        if (game_over == 1)        {            write_client_msg(WIN);        }        else if (game_over == 2)        {            write_client_msg(LOS);        }        else if (turns == 8)        {            write_client_msg(EGL);            game_over = 3;        }        ++turns;    }    close(sockfd);}int main(int argc, char** argv) {    printf(\nmain\n);    setup_listener();    while (1)    {        get_client();        // REQUESTS INT FOR SOME REASON        Play_game();    }    return (EXIT_SUCCESS);}And here is the client side:#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <netdb.h>#include <sys/types.h>#include <netinet/in.h>#include <sys/socket.h>#define MYPORT 5555;#define MY_BUFFER_SIZE 10;int sockfd;struct sockaddr_in their_addr;struct hostent *server;// Lit un message du socket serveur.void recv_msg(char * msg){    printf(\nrecv_msg\n);    // Tous les messages font 3 bytes.    memset(msg, 0, 4);    int n = read(sockfd, msg, 3);    if (n < 0 || n != 3)    {        perror(Erreur lors de la lecture de message sur le socket serv.);        exit(EXIT_FAILURE);    }}// Lit un entier du socket serveur.int recv_int(){    printf(\nrecv_int\n);    int msg = 0;    int n = read(sockfd, &msg, sizeof(int));    if (n < 0 || n != sizeof(int))     {        perror(Erreur lors de la lecture d'entier sur le socket serv.);        exit(EXIT_FAILURE);    }    return msg;}// Ecrit un entier sur le socket serveur.void write_server_int(int msg){    printf(\nwrite_server_int\n);    int n = write(sockfd, &msg, sizeof(int));    if (n < 0)            {        perror(Erreur lors de l'ecriture d'entier sur le socket serv.);        exit(EXIT_FAILURE);    }}int connect_to_server(char * hostname){    printf(\nconnect_to_server\n);    sockfd = socket(AF_INET, SOCK_STREAM, 0);    if (sockfd < 0)     {        perror(Erreur lors de l'ouverture du socket du serveur.);        exit(EXIT_FAILURE);    }    server = gethostbyname(hostname);    if (server == NULL)     {        perror(Erreur lors de la recherche du serveur (hostname));        exit(EXIT_FAILURE);    }    memset(&their_addr, 0, sizeof(their_addr));    their_addr.sin_family = AF_INET;    their_addr.sin_addr = *((struct in_addr*)server->h_addr);    //PORT    their_addr.sin_port = htons(5555);     if (connect(sockfd, (struct sockaddr *) &their_addr, sizeof(their_addr)) < 0)    {        perror(Erreur lors de la connection au serveur.);        exit(EXIT_FAILURE);    }}void draw_board(char board[3][3]){    printf(\ndraw_board\n);    printf( %c | %c | %c \n, board[0][0], board[0][1], board[0][2]);    printf(___________\n);    printf( %c | %c | %c \n, board[1][0], board[1][1], board[1][2]);    printf(___________\n);    printf( %c | %c | %c \n, board[2][0], board[2][1], board[2][2]);}void take_turn(){       printf(\ntake_turn\n);    //BUFFER_SIZE    char buffer[10];    while (1)     {        printf(Choisissez un nombre de 0 a 8 pour jouer.                Sur 0 commence la 1ere ligne, sur 3 la 2eme, sur 6 la 3eme.);        fgets(buffer, 10, stdin); // Lit ce qui est recu par l'utilisateur        // - '0' = -48 pour annuler les 48 premiers chr de la table ASCII        // Car stdin prend l'input en tant que char -> ASCII et move est un int        int move = buffer[0] - '0';        if (move <= 8 && move >= 0)        {            write_server_int(move);               break;        }         else            printf(\n);            printf(Mauvais input. Veuillez suivre les indications.);    }}void get_update(char board[3][3]){    printf(get_update);    // Recoit le placement de morpion du serveur.    int move = recv_int(sockfd);    // Met a jour le jeu.    board[move/3][move%3] = 'O';    }int main(int argc, char** argv) {    printf(main);    if (argc != 2)    {        perror(Veuillez specifier le nom de la machine distante en argument.);        exit(EXIT_FAILURE);    }    sockfd = connect_to_server(argv[1]);    printf(Waiting for server message to start.);    char msg[4];    char board[3][3] = { {' ', ' ', ' '}, {' ', ' ', ' '}, {' ', ' ', ' '} };    draw_board(board);    // THE ERROR HAPPENS HERE PLZ HELP    printf(Waiting for server message to start.);    do    {        recv_msg(msg);    }    while (strcmp(msg, GOO));    printf(msg);    draw_board(board);    while(1)    {        recv_msg(msg);        if (!strcmp(msg, TRC))        {            printf(A vous de jouer: );            take_turn(sockfd);        }        else if (!strcmp(msg, MAJ))        {            get_update(board);            draw_board(board);        }        else if (!strcmp(msg, WIN)) { /* Winner. */            printf(Victoire! Vous avez battu la machine.);            break;        }        else if (!strcmp(msg, LOS)) { /* Loser. */            printf(Vict... presque! On apprend beaucoup quand on perd <3);            break;        }        else if (!strcmp(msg, EGL)) { /* Game is a draw. */            printf(Egalite. Bah au moins vous avez pas perdu! Excellent.);            break;        }        printf(Revenez un de ces jours! Regardez comme je m'amuse...);        close(sockfd);        return 0;    }    return (EXIT_SUCCESS);}And here are both outputs when I try to run them:Server:mainsetup_listenerget_clientServeur:  connection recue du client 192.168.209.1Play_gameWriting message to client GOO. 0Writing message to client GOO. 1write_client_msgWriting message to client GOO. 2get_player_movewrite_client_msgrecv_intRUN TERMINATED (exit value 1, total time: 2m 3s)Client:E:\University\BA2\Algorithmique\OXO_Client>gcc client.c -o clientE:\University\BA2\Algorithmique\OXO_Client>client Reinstallmainconnect_to_serverWaiting for server message to start.draw_board   |   |___________   |   |___________   |   |Waiting for server message to start.recv_msgErreur lors de la lecture de message sur le socket serv.: No errorE:\University\BA2\Algorithmique\OXO_Client>The client is run through the terminal and receives the computer's name as an argument. As you can see, the server just sends its GOO message and doesn't care if the client receives it nor what it does with it.
Server / client desynchronisation of messages
c;socket;server;client