C 언어 4 창 채 팅 실현

C 언어 는 네 개의 창 채 팅 을 실현 합 니 다.여러분 이 참고 하 시기 바 랍 니 다.구체 적 인 내용 은 다음 과 같 습 니 다.
얼마 전에 배 운 공유 메모리,파이프,메시지 큐 등 프로 세 스 동기 화 체 제 를 연습 하기 위해 채 팅 프로젝트 를 만 들 었 습 니 다.
항목 설명:
4 개의 프로 세 스 가 있 습 니 다.A 프로 세 스 와 B 프로 세 스 는 통신 을 담당 하고 표준 입력 에서 읽 은 문자열 은 파 이 프 를 통 해 상대방 에 게 보 냅 니 다.A1 과 B1 프로 세 스 는 표 시 를 책임 집 니 다.그 중에서:
  • A 프로 세 스 와 B 프로 세 스 는 파 이 프 를 통 해 통신 하고 A 프로 세 스 와 A1 프로 세 스 는 공유 메모리 통신 을 통 해 B 프로 세 스 와 B1 프로 세 스 는 메시지 큐 를 통 해 통신 합 니 다
  • 4.567917.A 프로 세 스 는 표준 입력 에서 읽 은 문자열 을 파이프 와 공유 메모리 에 넣 고 파이프 에서 읽 은 문자열 을 공유 메모리 에 넣 습 니 다.B 프로 세 스 는 파이프 에서 A 가 넣 은 문자열 을 가 져 옵 니 다.A1 프로 세 스 는 공유 메모리 에서 문자열 을 가 져 와 화면 에 인쇄 합 니 다4.567917.B 프로 세 스 는 표준 입력 에서 읽 은 문자열 로 A 프로 세 스 를 보 내 고 메시지 큐 를 통 해 B1 프로 세 스 를 보 내 며 B1 프로 세 스 는 메시지 큐 에서 메 시 지 를 읽 고 화면 에 인쇄 합 니 다
  • 종료 시 A 와 B 의 임의의 프로 세 스에 서 Ctrl+c 또는 Ctrl+\를 입력 하면 네 프로 세 스 는 모든 파이프,공유 메모리,메시지 큐 등 자원 을 삭제 하고 질서 있 게 종료 합 니 다
  • 운영 체제:Ubuntu 20.4
    언어:c
    컴 파일 러:gcc
    func.h
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <time.h>
    #include <sys/mman.h>
    #include <fcntl.h>
    #include <sys/select.h>
    #include <sys/shm.h>
    #include <sys/sem.h>
    #include <sys/msg.h>
    #include <signal.h>
    
    #define ARGS_CHECK(argc, num){if(argc!=num){fprintf(stderr,"args error!
    "); return -1;}} #define ERROR_CHECK(ret,num,msg){if(ret == num){perror(msg); return -1;}}
    a.c
    
    //========= A   ===========
    //1.         ,         B  
    //2.   B         
    //3.          ,  B       A1
    //===========================
    
    #include <func.h>
    
    int chatA(int shmid, int semid, char *p);
    int sndToA1(int semid, int shmid, char *p, char *msg);//          A1
    void closeAll();//         ,           
    void sigFunc(int signum);//  2  3       ,   A    2  3      close  
    
    //    ,                
    int semid;
    int shmid;//    
    char *p;
    
    int fdWrite;
    int fdRead;
    
    int main()
    {
        //1.      ,              ,     
        semid = semget(2000, 1, IPC_CREAT|0666);
        ERROR_CHECK(semid, -1, "A semget");
        shmid = shmget(1000, 4096, IPC_CREAT|0666);//        
        ERROR_CHECK(shmid, -1, "shmget");
        p = (char *)shmat(shmid, NULL, 0);
    
        signal(SIGINT, sigFunc);
        signal(SIGQUIT, sigFunc);
    
        int ret = chatA(shmid, semid, p);
        ERROR_CHECK(ret, -1, "run A");//            
        return 0;
    }
    
    int chatA(int shmid, int semid, char *p){
        //      1,    -1
        fdRead = open("1.pipe", O_RDONLY);//         1
        ERROR_CHECK(fdRead, -1, "open fdRead");//        
        fdWrite = open("2.pipe", O_WRONLY);//         2
        ERROR_CHECK(fdWrite, -1, "open fdWrite");//  
        setbuf(stdin, NULL);
        puts("=========== A ===========");
        char buf[512] = {0};
        fd_set rdset;//      ,            
        while(1){
            struct timeval timeout;//    
            timeout.tv_sec = 5;
            timeout.tv_usec = 15000000;//  5            
            FD_ZERO(&rdset);//     ,    
            FD_SET(fdRead, &rdset);//       1      
            FD_SET(STDIN_FILENO, &rdset);//               
            int tret = select(fdRead + 1,&rdset,NULL,NULL,&timeout);//  select    
            if(tret == 0){
                puts("time out!");
            }
            //select    ,    FD  ,    
            //    ,      
            if(FD_ISSET(fdRead, &rdset)){
                //       ,        ,   A1
                memset(buf, 0, sizeof(buf));//  buf    ,          
                int ret = read(fdRead, buf, 1024);//           
                if(ret == 0){
                    //              ,    
                    sigFunc(2);
                    break;
                }
                //   B       
                int type = 0;
                sscanf(buf, "%*d %d", &type);//       ,1    ,2        
                int snd_ret = 0;
                
                switch (type){
                case 1:
                    //   1   ,              A1
                    snd_ret = sndToA1(shmid, semid, p, buf);
                    ERROR_CHECK(snd_ret, -1, "sndToA1");
                    break;
                case 2:
                    //=====    B    2   ,      =====
                    // A1      2   , A1    ,       
                    sigFunc(2);
                    exit(0);
                }
            }
            if(FD_ISSET(STDIN_FILENO, &rdset)){
                //          ,          ,   3   ,   A1 B
                time_t localtm;
                time(&localtm);//      
                localtm += 8*3600;
                memset(buf, 0, sizeof(buf));//  buf
                int ret = read(STDIN_FILENO, buf, 1024);//    
                if(ret == 0){
                    //              ,      
                    puts("I quite.");
                    break;
                }
                char sstoA1[1024] = {0};//      ,   A1   
                char sstoB[1024] = {0};//      ,   B   
                sprintf(sstoA1, "%ld %d %s", localtm, 3, buf); //          A1
                sprintf(sstoB, "%ld %d %s", localtm, 1, buf); //   1      B
                sndToA1(shmid, semid, p, sstoA1);//   A1
                write(fdWrite, sstoB, sizeof(sstoB));//       B
            }
        }
        close(fdRead);
        close(fdWrite);
        return 1;//        ,  1
    }
    
    int sndToA1(int shmid, int semid, char *p, char *msg){
        //           A1    
        //       ,              ,     
        struct sembuf V;
        V.sem_num = 0;
        V.sem_op = +1;
        V.sem_flg = SEM_UNDO;
        semop(semid, &V, 1);
        /* int shmid = shmget(1000, 4096, IPC_CREAT|0666);//         */
        ERROR_CHECK(shmid, -1, "shmget");
        /* char *p = (char *)shmat(shmid, NULL, 0); */
        memcpy(p, msg, strlen(msg));//         
        return 1;
    }
    
    void closeAll(){
        //               ,       
        write(fdWrite, "0 2 0", 5);//       B
        shmdt(p);
        shmctl(shmid, IPC_RMID, NULL);
        semctl(semid, IPC_RMID, 0);
        close(fdWrite);
        close(fdRead);
        exit(0);
    }
    
    void sigFunc(int signum){
        printf("Bye Bye.
    "); // 2 3 , A1, closeAll sndToA1(shmid, semid, p, "0 2 0");// A1 usleep(500); closeAll(); }
    b.c
    
    //========= B   ===========
    //1.         ,         A  
    //2.   A         
    //3.          ,  A       B1
    //===========================
    
    #include <func.h>
    
    //          ,   B1    
    typedef struct myMsg{
        long mtype;
        char mtext[512];
    }myMsg_t;
    
    int chatB(char *pipe1, char *pipe2);
    int sndToB1(int msqid, char *msg);//  A       B1
    void closeAll();
    void sigFunc(int signum);
    
    //    ,          
    int msqid;
    int fdWrite;
    int fdRead;
    
    int main()
    {
        msqid = msgget(3000, IPC_CREAT|0666);
        ERROR_CHECK(msqid, -1, "B msgget");
    
        //          
        signal(SIGINT, sigFunc);
        signal(SIGQUIT, sigFunc);
    
        int ret = chatB("./1.pipe", "./2.pipe");
        ERROR_CHECK(ret, -1, "run B");
        return 0;
    }
    
    int chatB(char *pipe1, char *pipe2){
        //    2,   2    ,   1   
        fdWrite = open(pipe1, O_WRONLY);
        ERROR_CHECK(fdWrite, -1, "open pipe1");
        fdRead = open(pipe2, O_RDONLY);
        ERROR_CHECK(fdRead, -1, "open pipe2");
        setbuf(stdin, NULL);
        puts("============ B ============");
        char buf[512] = {0};
        fd_set rdset;//    ,    
        while(1){
            //        
            struct timeval timeout;
            timeout.tv_sec = 5;
            timeout.tv_usec = 15000000;
            FD_ZERO(&rdset);//     
            FD_SET(fdRead, &rdset);
            FD_SET(STDIN_FILENO, &rdset);
            int tret = select(fdRead+1,&rdset,NULL,NULL,&timeout);
            if(tret == 0){
                puts("time out!");
            }
    
            //       ,      ,        
            if(FD_ISSET(fdRead, &rdset)){
                //       ,        B1
                memset(buf, 0, sizeof(buf));
                int ret = read(fdRead, buf, 1024);
                if(ret == 0){
                    sigFunc(2);
                    break;
                }
                int type = 0;//         
                sscanf(buf, "%*d %d", &type);//          
    
                //   2   ,      
                // B1      ,        ,     
                if(type == 2){
                    sigFunc(2);
                    exit(0);
                }
    
                //         ,   B1
                int snd_ret = sndToB1(msqid, buf);
                ERROR_CHECK(snd_ret, -1, "B sndToB1");
            }
            if(FD_ISSET(STDIN_FILENO, &rdset)){
                //          ,    ,    A B1
                time_t localtm;
                time(&localtm);//      
                localtm += 8*3600;
                memset(buf, 0, sizeof(buf));
                int ret = read(STDIN_FILENO, buf, 1024);
                if(ret == 0){
                    puts("I quite.");
                    break;
                }
                //             
                char sstoA[1024] = {0};//   A   
                sprintf(sstoA, "%ld %d %s", localtm, 1, buf); 
                write(fdWrite, sstoA, sizeof(sstoA));
    
                char sstoB1[1024] = {0};//   B1      3 
                sprintf(sstoB1, "%ld %d %s", localtm, 3, buf); 
                sndToB1(msqid, sstoB1);
            }
        }
        close(fdRead);
        close(fdWrite);
        return 1;//        ,  1
    }
    
    int sndToB1(int msqid, char *msg){
        //      ,      B1
        myMsg_t msgtoB1;//         
        msgtoB1.mtype = 1;
        memset(msgtoB1.mtext, 0, sizeof(msgtoB1.mtext));
        memcpy(msgtoB1.mtext, msg, strlen(msg));
        msgsnd(msqid, &msgtoB1, strlen(msg), 0);
        return 1;
    }
    
    void closeAll(){
        msgctl(msqid, IPC_RMID, 0);//      
        close(fdWrite);//    
        close(fdRead);
        exit(0);
    }
    
    void sigFunc(int signum){
        printf("Bye Bye.
    "); // , B1, , sndToB1(msqid, "0 2 0");// B1 write(fdWrite, "0 2 0", 5);// A usleep(500);// , B1 // 2 3 , closeAll closeAll(); }
    a1.c
    
    //========== A1 ==========
    //1.          
    //2.  
    
    int display();
    
    #include <func.h>
    
    int main()
    {
        int ret = display();
        ERROR_CHECK(ret, -1, "A1 display");
        return 0;
    }
    
    int display(){
        //1.          
        //       ,      ,      ,     
        //1.1         ,             ,              
        int semid = semget(2000, 1, IPC_CREAT|0666);
        ERROR_CHECK(semid, -1, "A1 semget");
        semctl(semid, 0, SETVAL, 0);//        0
        //     ,      ,       
        struct sembuf P;
        P.sem_num = 0;
        P.sem_op = -1;
        P.sem_flg = SEM_UNDO;
        printf("=========== A1 ===========
    "); while(1){ semop(semid, &P, 1);//P , int shmid = shmget(1000, 4096, IPC_CREAT|0666); ERROR_CHECK(shmid, -1, "A1 shmget"); char *p = (char *)shmat(shmid, NULL, 0);// int type = 0; sscanf(p, "%*d %d", &type);// , switch (type){ case 1: // B printf("<<<<<<<<< receive <<<<<<<<<<
    "); struct tm *ptm = NULL; time_t tmp = 0; char ss[512] = {0}; sscanf(p, "%ld", &tmp);// sscanf(p, "%*d %*d %[^
    ]", ss); ptm = gmtime(&tmp); printf("%4d-%02d-%02d %02d:%02d:%02d
    ", ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); puts(ss); printf("
    "); // memset(p, 0, 4096); break; case 2: printf("Bye Bye.
    "); shmdt(p); shmctl(shmid, IPC_RMID, NULL); exit(0); break; case 3: printf(">>>>>>>>> send >>>>>>>>>>>
    "); struct tm *ptm3 = NULL; time_t tmp3 = 0; char ss3[512] = {0}; sscanf(p, "%ld", &tmp3);// sscanf(p, "%*d %*d %[^
    ]", ss3); ptm3 = gmtime(&tmp3); printf("%4d-%02d-%02d %02d:%02d:%02d
    ", ptm3->tm_year+1900,ptm3->tm_mon+1,ptm3->tm_mday, ptm3->tm_hour, ptm3->tm_min, ptm3->tm_sec); puts(ss3); printf("
    "); // memset(p, 0, 4096); break; default: printf("sonething wrong!
    "); } } }
    b1.c
    
    //========== B1 ===========
    //    B   ,   
    
    #include <func.h>
    
    typedef struct myMsg{
        long mtype;
        char mtext[512];
    }myMsg_t;
    
    int display();
    
    int main()
    {
        int ret = display();
        ERROR_CHECK(ret, -1, "B1 display");
        return 0;
    }
    
    int display(){
        printf("=========== B1 ===========
    "); while(1){ // B int msqid = msgget(3000, IPC_CREAT|0666); ERROR_CHECK(msqid, -1, "B1 msgget"); myMsg_t msgfromB; memset(&msgfromB, 0, sizeof(msgfromB)); msgrcv(msqid, &msgfromB, sizeof(msgfromB.mtext), 1, 0); //1. 2 , int type = 0; sscanf(msgfromB.mtext, "%*d %d", &type);// , , switch (type){ case 1: // B printf("<<<<<<<<< receive <<<<<<<<<<
    "); struct tm *ptm = NULL; time_t tmp = 0; char ss[512] = {0}; sscanf(msgfromB.mtext, "%ld", &tmp);// sscanf(msgfromB.mtext, "%*d %*d %[^
    ]", ss); ptm = gmtime(&tmp); printf("%4d-%02d-%02d %02d:%02d:%02d
    ", ptm->tm_year+1900,ptm->tm_mon+1,ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec); puts(ss); printf("
    "); // break; case 2: // printf("Bye Bye.
    "); msgctl(msqid, IPC_RMID, NULL); exit(0); case 3: printf(">>>>>>>>> send >>>>>>>>>>>
    "); struct tm *ptm3 = NULL; time_t tmp3 = 0; char ss3[512] = {0}; sscanf(msgfromB.mtext, "%ld", &tmp3);// sscanf(msgfromB.mtext, "%*d %*d %[^
    ]", ss3); ptm3 = gmtime(&tmp3); printf("%4d-%02d-%02d %02d:%02d:%02d
    ", ptm3->tm_year+1900,ptm3->tm_mon+1,ptm3->tm_mday, ptm3->tm_hour, ptm3->tm_min, ptm3->tm_sec); puts(ss3); printf("
    "); break; default: printf("Something wrong!
    "); } } }
    다음 과 같이 실행:

    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기