创建我的第一个Unix服务器/客户端,但得到"shmget:无效的参数"错误,可能还有更多.[C]

Lil*_*nks 2 c unix tcp-ip

我正在做一个Unix,C分配.我正在创建一个服务器和一个将相互交互的客户端.我对TCP/IP编程不是很有经验,所以我为提前缓慢道歉.

首先,我正在尝试创建我的设置的基本布局.我使用Makefile编译客户端和服务器,它完美地工作.但是,当我执行服务器时,我收到此错误:

shmget: Invalid argument
Run Code Online (Sandbox Code Playgroud)

我认为这是IPC资源的问题.我应该使用atexit()删除IPC资源,但我不认为我做得对.

这是server.c的代码,如果它有帮助:

#include "server.h"

int shmid, semid;
struct Shared *shm;

int main() {
    key_t shmkey = 0x6060, semkey = 0x6061;
    char *s, c;
    unsigned short zeros[2] = {0, 0};

    int srvrFd, clntFd, clntAdrLen, i; //socket
    struct sockaddr_in srvrAddr, clntAddr;
    char buf[256];

    if(atexit(server_exit) != 0) {
            perror("failed to attach atexit()");
            _exit(EXIT_FAILURE);
    }
    /* Create an array of 2 semaphores with key. */
    semid = semget(semkey, 2, 0666 | IPC_CREAT);
    if (semid < 0) {
            perror("semget");
            exit(0);
    }
    /* Set the values of semaphores */
    argument.array = zeros;
    if (semctl(semid, 0, SETALL, argument) < 0) {
            printf("Cannot init semaphore 0.\n");
    }

    /* Create the segment. */
    if ((shmid=shmget(shmkey, sizeof(struct Shared), IPC_CREAT|0666))<0) {
            perror("shmget");
            exit(1);
    }

    /* Attach the segment to our data space. */
    if ((shm=shmat(shmid, NULL, 0))==(struct Shared *)-1) {
            perror("shmat");
            exit(1);
    }
    /* Put some things into the shared memory. */
    s = shm->text;
    for (c = 'a'; c<= 'z'; c++) {
            *s++ = c;
    }
    *s = '\0';
    shm->number = 123;

    //socket
    srvrFd = socket(AF_INET, SOCK_STREAM, 0);
    if(srvrFd < 0) {
            perror("socket");
            exit(1);
    }
    srvrAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    srvrAddr.sin_port = htons(6060);
    if(bind(srvrFd, (struct sockaddr *)&srvrAddr, sizeof(srvrAddr)) < 0) {
            perror("bind");
            exit(1);
    }
    listen(srvrFd, 5);
    while(1) {
            clntAdrLen = sizeof(clntAddr);
            clntFd = accept(srvrFd, (struct sockaddr*)&clntAddr, NULL);
            if (fork() == 0) { //we're in the child
                    i = recv(clntFd, buf, sizeof buf, 0);
                    send(clntFd, buf, i, 0);
                    close(clntFd);
                    exit(0);
            } else { //we're in the parent
                    close(clntFd);
            }
    }
}

void server_exit(void)
{
    if(shm != NULL) {
            shmdt(shm);
    }
    if(semid != -1) {
            semctl(semid, 0, IPC_RMID);
    }
    if(shmid != -1) {
            shmctl(shmid, IPC_RMID, 0);
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢阅读.

编辑:结构的定义..

struct Shared {
    char text[27];
    int number;
} ;
Run Code Online (Sandbox Code Playgroud)

xax*_*xon 6

http://linux.die.net/man/2/shmget

看起来要么段存在并且它比您要求的要小,要么您尝试创建一个新段,但它小于系统最小大小(SHMMIN)或大于最大值(SHMMAX)

编辑:事实证明这是它 - 它已经存在并且比你要求的要小.您必须将其创建为大小为27,28,29,30或31,因为它适用于27而不是32.如果运行unix命令行程序ipcs,它将显示所有现有的共享内存段:

key        shmid      owner      perms      bytes      nattch     status      
0x00000001 0          ec2-user   666        32         0                       
Run Code Online (Sandbox Code Playgroud)

然后ipcrm -M <key>将删除它.

从我所看到的,您可能不想使用SYS-V共享内存.如果可以,请使用POSIX.以下是POSIX共享内存接口的参考:

http://man7.org/linux/man-pages/man7/shm_overview.7.html

还看看:

http://www.cs.cf.ac.uk/Dave/C/node27.html

对于两者的指南,但我更喜欢POSIX(如果可用的话)(除非你在像DEC Alpha这样的旧系统上)