server.h

// server.h
#ifndef SERVER_H
#define SERVER_H

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <signal.h>
#define MAXLINE 256
#define MAX_PLAYERS 3

struct inventory {
    int seed[14];
    int corp[14];
    int booster;
};

struct Player {
    char name[MAXLINE];
    struct inventory inventory[MAXLINE];
    int money[MAXLINE];
    int active;
    int pid;
};

extern int playerCount;
extern struct Player* sharedMemory[MAX_PLAYERS];

#endif

server.c

//server.c
#include "server.h"

int playerCount = 0;
struct Player* sharedMemory[MAX_PLAYERS];

void sendSignalToClients();
void sendSignalToClients1();


int main() {
    int playerIndex = 0;
    key_t key;

    int keyFile = open("keyfile", O_RDWR | O_CREAT, 0666);
    if (keyFile == -1) {
        perror("keyfile");
        exit(EXIT_FAILURE);
    }

    if (read(keyFile, &key, sizeof(key)) != sizeof(key)) {
        key = ftok("/home/g_202010953/FARM/save", 1);
        write(keyFile, &key, sizeof(key));
    }

    close(keyFile);

    int shmid = shmget(key, sizeof(struct Player) * MAX_PLAYERS, 0666 | IPC_CREAT);
    if (shmid == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < MAX_PLAYERS; ++i) {
        sharedMemory[i] = (struct Player*)shmat(shmid, NULL, 0);
        if (sharedMemory[i] == (struct Player*)-1) {
            perror("shmat");
            exit(EXIT_FAILURE);
        }
    }


    mkfifo("pipe", 0666);
    mkfifo("pipe1", 0666);
    int fd1 = open("pipe", O_RDONLY);
    int fd2 = open("pipe1", O_WRONLY);

    while (1) {
        char buffer[MAXLINE];
        read(fd1, buffer, sizeof(buffer));

        if (strcmp(buffer, "exit") == 0) {
            break;type here
        }

        
        if (playerCount < MAX_PLAYERS) {
            strcpy(sharedMemory[playerIndex]->name, buffer);
            sharedMemory[playerIndex]->active = 1;
            sharedMemory[playerIndex]->pid = getpid();
            playerIndex++;
            playerCount++;

            printf("player[%d] visit: %s\n", playerCount, buffer);
            sendSignalToClients1();
        }



        if (playerCount == MAX_PLAYERS) {
            sendSignalToClients();
        }


    }

    close(fd1);
    close(fd2);
    unlink("pipe");
    unlink("pipe1");


    for (int i = 0; i < MAX_PLAYERS; ++i) {
        shmdt(sharedMemory[i]);
    }

    return 0;
}

void sendSignalToClients() {
    pid_t* clientPid;

    for (int i = 0; i < MAX_PLAYERS; ++i) {
        if (sharedMemory[i]->active) {
            clientPid = (pid_t*)(&(sharedMemory[i]->pid));  
            kill(*clientPid, SIGUSR1);
        }
    }
}

void sendSignalToClients1() {
    pid_t* clientPid;

    for (int i = 0; i < MAX_PLAYERS; ++i) {
        if (sharedMemory[i]->active) {
            clientPid = (pid_t*)(&(sharedMemory[i]->pid));  
            kill(*clientPid, SIGUSR2);
        }
    }
}

client.c

//client.c
#include "server.h"

int fd1, fd2;
int num;

void select_conversation() {

    scanf("%d", &num);
    switch (num) {
    case 1:
        break;
    case 2:
        break;
    case 3:
        break;
    case 4:
        break;
    case 5:
        break;
    case 6:
        break;

    default:
        break;
    }
}
void handleSignal(int signum);

void handlePlayerNamesSignal(int signum);

int main() {
    key_t key;
    int shmid;
    int keyFile = open("keyfile", O_RDONLY);

    if (keyFile == -1) {
        perror("keyopen");
        exit(EXIT_FAILURE);
    }

    if (read(keyFile, &key, sizeof(key)) != sizeof(key)) {
        perror("keyfile");
        close(keyFile);
        exit(EXIT_FAILURE);
    }

    close(keyFile);

    shmid = shmget(key, sizeof(struct Player) * MAX_PLAYERS, 0666 | IPC_CREAT);
    if (shmid == -1) {
        perror("shmget");
        exit(EXIT_FAILURE);
    }

    for (int i = 0; i < MAX_PLAYERS; ++i) {
        sharedMemory[i] = (struct Player*)shmat(shmid, NULL, 0);
        if (sharedMemory[i] == (struct Player*)-1) {
            perror("shmat");
            exit(EXIT_FAILURE);
        }
    }

    fd1 = open("pipe", O_WRONLY);
    fd2 = open("pipe1", O_RDONLY);

    if (fd1 == -1 || fd2 == -1) {
        perror("pipe error");
        exit(EXIT_FAILURE);
    }

    char playerName[MAXLINE];

    printf("input playername : ");
    fgets(playerName, MAXLINE, stdin);
    playerName[strcspn(playerName, "\n")] = '\0';

    write(fd1, playerName, sizeof(playerName));

    signal(SIGUSR2, handlePlayerNamesSignal);
    signal(SIGUSR1, handleSignal);

    for (int i = 0; i < MAX_PLAYERS; ++i) {
        shmdt(sharedMemory[i]);
    }


    close(fd1);
    close(fd2);

    return 0;
}


void handleSignal(int signum) {
    if (signum == SIGUSR1) {
        printf("SIGUSR1. maingame start.\n");
        select_conversation();
    }
}

void handlePlayerNamesSignal(int signum) {
    if (signum == SIGUSR2) {
        printf("SIGUSR2. player name list:\n");


        for (int i = 0; i < MAX_PLAYERS; ++i) {
            if (sharedMemory[i]->active) {
                printf("Player[%d] : %s\n", i + 1, sharedMemory[i]->name);
            }
        }
    }
}

当GCC-o客户端.c时,未定义对`sharedMemory的引用

我在头文件中声明了共享内存,并在server.c中定义了它,但我不知道为什么会出现这个错误.

推荐答案

我在头文件中声明了共享内存,并在server.c中定义了它,但我不知道为什么会出现这个错误.

它的出现是因为server.c只是服务器程序的一部分.它对变量sharedMemory的定义确保了服务器程序具有这样的变量,但这对单独的客户端程序没有任何作用.它需要自己对对象进行定义.如果是我,我会把它分解到一个单独的.c文件中,然后我会在两个程序中使用它.

话虽如此,这个建筑似乎很奇怪.你似乎在写某种多人游戏.在这种情况下,操作的自然模式将是

  1. 服务器调解玩家之间的所有交互,或者
  2. 玩家之间直接互动.

对于情况(1),我不明白为什么客户端需要为多个玩家的数据访问共享内存.

对于情况(2),我看不出服务器程序应该扮演什么角色,特别是需要访问球员数据的程序.

C++相关问答推荐

用gcc-msse 2编译的C程序包含AVX 1指令

为什么指针运算会产生错误的结果?

我的C函数起作用了,但我不确定为什么

这个空指针类型的转换是有效代码还是恶意代码?

C语言中MPI发送接收字符串时出现的分段错误

为什么我在C代码中得到一个不完整的类型?

如何将大写/小写土耳其字母相互转换?

当用C打印过多的';\n';时输出不正确

为什么孤儿进程在 Linux 中没有被 PID 1 采用,就像我读过的一本书中声称的那样?

Linux memcpy 限制关键字语法

与 C 相比,C++ 中无副作用的无限循环的好处是 UB?

可以从指针数组中的值初始化指针吗?

C23 中是否有 __attribute__((nonnull)) 的等效项?

int 与 size_t 与 long

我如何(合规地)从 tmpfile() 读取?

一个按位表达式,当 mask 全部为零时返回 1,当 mask 全部为 1 时返回 x

当 GCC 的预处理器删除了注释时,它如何知道错误位置(在源代码中)?

__VA_ARGS__ 中的逗号导致宏定义扩展错误

在C中隐藏init struct 体并使用init函数

如何 Select 4x4矩阵乘法函数的变型?