2

我正在做一个 Unix,C 作业。我正在创建一个服务器和一个客户端,它们将相互交互。我对 TCP/IP 编程不是很有经验,所以我很抱歉提前很慢。

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

shmget: Invalid argument

我认为这是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);
    }
}

谢谢阅读。

编辑:结构的定义..

struct Shared {
    char text[27];
    int number;
} ;
4

1 回答 1

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                       

然后ipcrm -M <key>将其删除。

从我所见,您可能不想使用 SYS-V 共享内存。如果可以,请使用 POSIX。这是 POSIX Shared Memory 接口的参考:

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

另请查看:

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

两者的指南,但如果它可用,我更喜欢 POSIX(除非你使用像 DEC Alpha 这样的非常旧的系统)

于 2013-05-19T00:20:57.153 回答