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 共有メモリ インターフェイスのリファレンスは次のとおりです。

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 に答える