2012-01-23 3 views
0

Я делаю сервер для простой игры памяти.Сервер в процессах обработки декомпозиции при обработке ответов сервера клиенту

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

Это пример того, как работает игра может память: Memory game example
И я решить проблему с управлением что-то вроде игры «сессий».
Сервер находится на C и клиент в Java, все это запустит на linux. Таким образом, это справочная информация.
У меня будет один сервер и n клиентов.
Мотивация:
1. Сервер начинается с некоторых адресов и портов.
2. клиенты могут подключаться к серверу.
3. сервер будет управлять играми.
сервер Ситуация:
game1 -client1, client2
Game2 -client3, client4
...
Gamen-clientX, clientY. (примечание: N, очевидно, не такое же, как n)
Число игр будет около 10.
Если клиентов больше, чем серверов - им будет стыдно .. Я как-то скажу им, что сервер заполнен.
каждая игра представлена ​​массивом из 64 значений int - она ​​представляет числа значков может быть также массив длины bool 64 и некоторых переменных (но это просто детали)
этот массив и переменные будут представлять состояние каждой игры и сервер и клиент будут обмениваться строковыми сообщениями, я их декодирую и обновляю состояние игры.
Что я имею ввиду под управлением игры:
В начале нет сервера, поэтому я запускаю сервер (может существовать только один экземпляр).
1.Server ждет подключения клиентов, на сервере нет игры.
2. Я запускаю клиент, клиент решает подключить сервер (ip, порт). Сервер отправляет клиенту состояние сервера - есть ли игры? если да, то какие игры = (дескриптор игр можно обрабатывать с играми)? 3. У клиента есть от 1 до 3 опций:
-a) создать игру = сервер генерировать состояние игры в режиме ожидания, отправить информацию клиенту (если нет на сервере клиента, очевидно, будет только этот вариант).
-b) если есть некоторые игры, клиент может подключиться к «подготовленной игре» = какой-то другой клиент создал игру и ждет противника; клиент получает информацию о состоянии авубы и устанавливает свой сервер регистрации состояния игры. c) была уже начата игра, но один клиент по какой-то причине потерял соединение, поэтому клиент хочет подключиться к игре, которая находится в процессе - если будут приняты некоторые условия, сервер отправит ему игровое состояние, чтобы может продолжаться
4. Игра, в которой есть 2 клиента, может начинаться.
5. Клиент, который в движении может нажать на кнопку, чтобы клиент получил сообщение, описывающее это действие. 0 сервер: 0: 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; 
} 

Так что мой вопрос: я должен служить каждому клиенту или игру в отдельном процессе и нуждаются в помощи с разложением. Где я должен помещать переменные (массивы, переменные) для каждой игры? Согласно fork().

+0

Для танго требуется два режима: вы прорабатываете процесс для каждого запроса на соединение, поэтому игроки будут жить в разных местах и ​​не могут общаться. Хорошо: они могли бы, если каждый клиент начал соединение с базой данных. Но эта база данных также должна будет управлять * игровым состоянием *. Классическим способом для этого является наличие * монолитного * сервера, который одновременно обрабатывает все соединения (и ассоциации между ними). Также: чтение() за один байт за раз не выиграет награду за производительность, вам нужно добавить некоторый код буферизации. – wildplasser

+0

Это школьная работа, я должен служить игрокам и играм параллельно, это одно из условий, которые мы получили. – user1097772

+0

Этот код, который я добавил в свой квесто, основан на некотором коде, который мы делали в школе, как сделать параллельный сервер. Я не буду использовать базу данных. У меня должен быть Java для клиентов и C для сервера. Таким образом, самый простой способ сделать работу связи - отправить некоторую строку с сообщением, которое объясняет, что объясняет действие и возвращает другое сообщение, объясняющее реакцию, и просто «расшифровывает это сообщение». Моя самая большая проблема заключается в том, что делать с игровыми данными и что должно включать разветвленную часть ... – user1097772

ответ

0

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

+0

Я думал о том, чтобы помещать эти структуры скорее в вилку - каждый процесс игры - я не знаю. Если это лучшая идея, и решение проблем может быть решено переменными, которые находятся в движении, поэтому, если игрок, который не находится на двигаться делать действие ничего не происходит - соответственно никаких изменений. Но я не знаю, как обращаться с тем, что два клиента обслуживаются одним процессом - я имею в виду, как получить правильный процесс. Например: game1 находится в proces no.1, а клиенты 1 и 2 подключены к игре1, поэтому они будут обслуживаться этим процессом .. если это возможно написать это так ... – user1097772

+0

Это совсем другая архитектура, потому что на момент у вас есть один процесс на клиента, который является общим разветвленным шаблоном сервера. Невозможно иметь один процесс за игру, но было бы сложнее реализовать, и я не вижу никакой пользы. –

+0

Хорошо, это была просто идея ... Итак, если я выбрал один процесс = один клиент, то что лучше: постоянно ли процесс активен, когда клиент подключен к игре или создает новый процесс каждый раз, когда клиент предпринимает какие-то действия? – user1097772

Смежные вопросы