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++相关问答推荐

为指针 struct 创建宏

librsvg rsvg_handle_get_dimensions获取像素大小与浏览器中的渲染大小没有不同

想了解 struct 指针和空指针转换

C指针算法在函数参数中的应用

C中的__attributor__((aligned(4),packed))与 struct 的用法

为什么在Linux(特别是Ubuntu 20.04LTS)上,POSIX共享内存对象在重启后仍然存在,然后突然变成了根用户?

_泛型控制表达式涉及数组碰撞警告的L值转换错误?

变量的作用域是否在C中的循环未定义行为或实现定义行为的参数中初始化?

是否定义了此函数的行为?

对于STM32微控制器,全局偏移表.get和.Got.plt必须为零初始化

RISC-V GCC编译器错误编译ASM代码

C 程序不显示任何输出,但它接受 CS50 Lab1 的输入问题

execve 不给出which命令的输出

这些表达式是否涉及 C 中定义的复合文字?

为什么 Linux 共享库 .so 在内存中可能比在磁盘上大?

如何修复数组数据与列标题未对齐的问题?

在链表中插入一个值

在 C23 之前如何对空指针使用nullptr?

仅使用其内存地址取消引用 C 中的 struct

如何在C中以0x格式打印十六进制值