私は単純なメモリゲーム用のサーバを作っています。クライアントのサーバレスポンスを管理する際のC分解処理のサーバ
私のプログラムでは分解に少し助けが必要ですが、私が望むのは分かっていますが、fork()を使って多くの経験をしていないので、C言語でどう書くべきかわかりません。私の目的は、私のサーバーの "SKELETON"の説明です。メッセージを送受信し、警告もエラーもなくコンパイルしました。最後に私の質問をします。 Memory game example
そして、私はゲームの「セッション」のようなものを管理して問題を解決しています:
は、これは可能性メモリーゲームがどのように機能するかの例です。
サーバーはCにあり、クライアントはJavaで、すべてLinux上で実行します。だからそれは背景情報です。
私は1台のサーバーとクライアントを持っています。
私の動機は:
です。1.サーバーは、いくつかのアドレスとポートで起動します。
2.クライアントはサーバーに接続できます。
3.サーバーゲームを管理します。
状況サーバー:
game1 -client1、CLIENT2
game2の-client3、client4
...
gameN-clientX、clientYプロパティ。 (注:Nは明らかにnと同じではありません)
ゲームの数は約10になります。
サーバより多くのクライアントがある場合、彼らは残念です。私は何とかサーバがいっぱいであることを彼らに伝えます。
各ゲームは64個のint値の配列で表されます。これはアイコンの数を表します boolの長さ64といくつかの変数の配列も可能ですが(詳細はちょっとです)
この配列と変数は各ゲームの状態を表しますサーバーとクライアントは文字列メッセージで通信し、それらをデコードしてゲームの状態を更新します。
ゲーム管理の意味:
最初はサーバーがないため、サーバーを実行しています(インスタンスが1つしか存在しない可能性があります)。
1.サーバーはクライアントの接続を待機し、サーバー上にゲームはありません。
2.私はクライアントを実行し、クライアントはサーバー(IP、ポート)に接続することを決定します。サーバはクライアントのサーバ状態に送ります - ゲームはありますか?はいの場合、どのゲーム=(ゲームで扱えるゲームの記述子)ですか? 3.クライアントは1から3のオプションを持っています:
-a)ゲームを作成する=サーバーはスタッキングのゲーム状態を生成し、クライアントに情報を送信します(サーバークライアント上のゲームがない場合は、このオプションのみです)。
-b)ゲームクライアントが「準備ゲーム」に接続できる場合、他のクライアントがゲームを作成して対戦相手を待つことができます。クライアントは情報のゲームの状態を取得し、彼のゲームの状態の記録サーバーを設定します。 c)既にゲームが進行中でしたが、何らかの理由で1つのクライアントが接続を失ったため、クライアントは進行中のゲームに接続し直したいと思っています - 条件が受け入れられると、サーバーはゲーム状態を送信します続けることができます
4. 2人のクライアントを持つゲームは始めることができます。
5.移動中にボタンをクリックできるクライアントは、そのアクションを説明するメッセージを取得します。
6.サーバーは、アクションが処理される方法を決定し、クライアントの両方にメッセージを送信します(OBSERVERなど)何がすべきか、クライアントはおそらくメッセージを確認するでしょうが、これはもう少し詳しくです
7。サーバーがクラッシュしたり、ゲームが終了する前に閉じられる場合、すべてのゲームが失われます。私はちょうどサーバーがダウンしているようなクライアントで何かメッセージを書いて終了します
8.ゲームが正しく終了したら - ゲームが終了するか、または1つのクライアントがメニュー終了ゲームを終了してゲームを終了することを決定した場合、サーバはクライアントにゲームの終了を知らせるために何かを行い、ゲームはゲームのリストを削除し、私のサーバーの
コード:
#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()によると。
タンゴには2回かかります。接続要求ごとにプロセスをフォークするので、プレイヤーはすべて異なるスペースに住み、通信できなくなります。まあ、すべてのクライアントがデータベースへの接続を開始した場合でも可能です。しかし、そのデータベースは*ゲームの状態*を管理する必要があります。このための古典的な方法は、すべての接続(とそれらの間の関連)を同時に扱う* monolitic *サーバーを持つことです。また、一度に1バイトずつread()を行うと、パフォーマンス賞を獲得できません。バッファリングコードを追加する必要があります。 – wildplasser
それは学校の仕事です、私はプレーヤーとゲームを提供する必要がありますそれは我々が持っている状態の一つです。 – user1097772
私のquestioに追加したこのコードは、私たちが学校で行ったいくつかのコード、パラレルサーバーの作り方に基づいています。私はデータベースを使用しません。 クライアント用のjavaとサーバー用のCが必要です。したがって、コミュニケーション作業を行う最も簡単な方法は、アクションを説明するものを説明するメッセージを含む文字列を送信し、反応を説明し、単にこのメッセージをデコードする別のメッセージを返すことです。 私の最大の問題は、ゲームデータと何をするべきか、そしてフォークされた部分を含めるべきかということです。 – user1097772