Процессы декомпозиции сервера в C при управлении ответами сервера клиенту - PullRequest
0 голосов
/ 24 января 2012

Я делаю сервер для простой Memory Game.

Мне нужна небольшая помощь с разложением в моей программе, я знаю, чего хочу, но я не знаю, как мне написать это на Cпотому что у меня не так много опыта с использованием fork ().Есть описание моих целей, «СКЕЛЕТОН» моего сервера - работа по отправке и получению сообщений, скомпилированная без предупреждений или ошибок, В КОНЦЕ Я задам свой вопрос.

Это пример того, как можноИгра памяти работает: Пример игры памяти И я решаю проблему с управлением чем-то вроде игровых «сессий».Сервер находится на C, а клиент на Java, все будут работать на Linux.Так что это фоновая информация.У меня будет один сервер и n клиентов.
Моя мотивация:1. Сервер запускается по какому-то адресу и порту.2. клиенты могут подключаться к серверу.3. сервер будет управлять играми .Ситуационный сервер:game1 -client1, client2game2 -client3, client4...gameN-clientX, clientY.(примечание: N явно не совпадает с n)Количество игр будет около 10.Если клиентов больше, чем сервера - им стыдно .. Я как-то скажу им, что сервер переполнен.каждая игра представлена ​​массивом из 64 значений int - она ​​представляет количество значков, может быть также массивом длины bool 64 и некоторыми переменными (но это просто детализация)этот массив и переменные будут представлять состояние каждой игры, а сервер и клиент будут обмениваться сообщениями в виде строк, я их декодирую и обновляю состояние игры. Что я имею в виду под управлением игрой: В начале нет сервера, поэтому я запускаю сервер (может существовать только один экземпляр).1. Сервер ждет подключения клиентов, игры на сервере нет.2. Я запускаю клиент, клиент решает подключить сервер (ip, port).Сервер отправляет клиенту состояние сервера - есть ли игры?если да, то какие игры = (дескриптор игр, чтобы можно было справляться с играми)?3. Клиент имеет от 1 до 3 вариантов:-a) create game = server генерировать начальное игровое состояние, отправлять информацию клиенту (если на сервере нет игры, очевидно, клиент имеет только эту опцию).-b) если там какой-либо клиент игры может подключиться к «подготовленной игре» = другой клиент создал игру и дождаться оппонента;Клиент получает информацию о состоянии игры и устанавливает свой сервер регистрации состояния игры.c) уже была какая-то игра в процессе, но один клиент по какой-то причине потерял соединение, поэтому клиент хочет подключиться обратно к игре, которая находится в процессе - если некоторые условия будут приняты, сервер отправит ему состояние игры, чтобыПродолжить4. Игра, в которой есть 2 клиента, может начаться.5. Клиент, который на ходу может нажать на кнопку, чтобы клиент получил сообщение, которое описывает это действие6. Сервер решает, как будет выполняться действие, и отправляет сообщение ОБА клиентов (что-то вроде OBSERVER). Что делать, клиенты, вероятно, подтверждают сообщение, но это опять-таки просто подробно.7. Если сбой сервера или его закрытие до окончания игр, все игры будут потеряны, я просто делаю в клиентах что-то вроде, если сервер не работает, они напишут какое-то сообщение и завершат8. Если игра закончилась правильно - игра заканчивается, или один клиент решает завершить игру, выбрав в меню «конец игры», сервер делает все необходимое, чтобы уведомить клиентов об окончании игры, и игра будет удалена из списка игр, и будетснова позиция для новой игры.

Код моего сервера:

#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <sys/un.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h> // kvuli inet_ntop
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>

#define MYADDRESS "127.0.0.1"  // the port users will be connecting to
#define MYPORT 10000  // the port users will be connecting to
#define MYFRONTA 10 // length of queue
#define MYMSGLEN 80 //max len of message

int sendMessage(char* msg, int socket){
    int length = strlen(msg);
    int ret;

    ret = write(socket, msg, length);
    return ret;
}

int readLine(void *vptr, size_t maxlen, int sockd) {
    int n, rc;
    char    c, *buffer;

    buffer = vptr;

    for ( n = 1; n < maxlen; n++ ) {

        if ( (rc = read(sockd, &c, 1)) == 1 ) {
            *buffer++ = c;
            if ( c == '\n' )
                break;
        }
        else if ( rc == 0 ) {
            if ( n == 1 )
                return 0;
            else
                break;
        }

    }

    *buffer = 0;
    return n;
}

int main(int argc, char **argv)
{
    int server_sockfd, client_sockfd;
    socklen_t server_len, client_len;
    struct sockaddr_in server_address;
    struct sockaddr_in client_address;

    server_sockfd = socket( AF_INET, SOCK_STREAM, 0 );
    server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = inet_addr( MYADDRESS );
    server_address.sin_port = htons( MYPORT );

    server_len = sizeof( server_address );
    //If the server binding fails
        if( bind( server_sockfd, ( struct sockaddr *)&server_address, server_len ) != 0 )
        {
                perror("oops: server-tcp-single");
                exit( 1 );
        }

    listen( server_sockfd, MYFRONTA );

    signal( SIGCHLD, SIG_IGN );//Zombie process protection

    while( 1 )
    {
        printf( "server wait...\n" );

        client_len = sizeof( client_address );
        client_sockfd = accept( server_sockfd, ( struct sockaddr *)&client_address, &client_len );
        //Info
        char str[INET_ADDRSTRLEN];
        inet_ntop(AF_INET,&(client_address.sin_addr), str, INET_ADDRSTRLEN);
        printf( "Connected client from %s\n", str );

        if( fork() == 0 )
        {
            char retezec[MYMSGLEN];
            readLine(retezec, MYMSGLEN, client_sockfd);

            printf( "Klient sent : %s\n", retezec );
            printf( "Server sends : %s\n", retezec );
            sendMessage(retezec, client_sockfd);
                close( client_sockfd );

            exit (0 );
        }
        else
            close( client_sockfd );

    }
    return EXIT_SUCCESS;
}

Итак, мой вопрос: я должен обслуживать каждого клиента или игру в отдельном процессе и мне нужна помощь с декомпозицией,Где я должен разместить переменные (массивы, переменные) для каждой игры?По вилке ().

1 Ответ

0 голосов
/ 24 января 2012

Вы можете поместить структуры данных, содержащие игры, в верхнюю часть main(), но вам нужно будет защитить их от одновременного доступа разветвленных процессов, используя что-то вроде семафор .

...