• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 200, comments - 8, trackbacks - 0, articles - 0

            一.基于文件的通信
              1.普通文件(io/mmap)
              2.有名管道文件
              3.匿名管道
              4.Socket

            二.基于內存的通信
              0.一組內核內存的工具
                ipcs  
                ipcs -m
                ipcs -q
                ipcs -s      
                ipcrm -q 編號ID
              1.普通的父子進程之間的匿名內存共享映射
              2.內核共享內存
               編程模型
                 2.1.創建共享內存,得到一個ID  shmget
                 2.2.把ID映射成虛擬地址(把內核中的緩存連接到用戶進程)  shmat
                 2.3.使用虛擬地址訪問內核共享內存 使用任何內存函數與運算符號            
                 2.4.卸載虛擬地址 shmdt
                 2.5.刪除共享內存 shctl(修改/獲取共享內存的屬性) 
                 
               共享內存的屬性  
                 
            案例:
               A.創建共享內存,并且修改內存數據。
               1.創建共享內存

             int shmget(key_t key,//為什么需要key
                                     int size,//共享內存大小
                                     int flags//共享內存的屬性與權限
                        )
                為什么要key_t:
                    約定創建與訪問的是同一個共享內存。
                  第三個參數:
                     方式|權限
                     方式:創建 IPC_CREAT  IPC_EXCL
                     打開:0 
                    常見的兩種方式:
                      創建:IPC_CREAT|IPC_EXCL | 0666;
                      打開:0
                       
                 返回:
                   成功返回共享內存ID
                   失敗返回-1   
               B.根據ID得到共享,并且訪問內存數據。
             void shmat(int id,
                        void *startaddr,//0:系統指定首地址
                        int flags)//掛載方式,建議0,可以使用IPC_RDONLY
            C.刪除
             int shmctl(int id,//被操作的共享內存ID
                        int how,//操作方式:一共三種操作
                        struct shmid_ds*ds)//共享內存屬性
                 how:
                   IPC_STAT
                   IPC_SET
                   IPC_RMID 

            #include <stdio.h>
            #include <string.h>
            #include <stdlib.h>
            #include <unistd.h>
            #include <signal.h>
            #include <sys/shm.h>
            #include <sys/ipc.h>
            key_t key;
            int shmid;
            int *p;
            int i=0;
            void deal(int s)
            {
                if(s==SIGINT)
                {
                    //4.卸載共享內存shmdt
                    shmdt(p);
                    //5.刪除共享內存shctl
                    shmctl(shmid,IPC_RMID,0);
                    exit(0);
                }
            }
            main()
            {
                
                signal(SIGINT,deal);
                //1.創建共享內存shmget
                key=ftok(".",255);
                if(key==-1) printf("ftok error:%m\n"),exit(-1);
                
                shmid=shmget(key,4,IPC_CREAT|IPC_EXCL|0666);
                if(shmid==-1) printf("get error:%m\n"),exit(-1);
                //2.掛載共享內存shmat
                p=shmat(shmid,0,0);
                if(p==(int*)-1) printf("at error:%m\n"),exit(-1);
                //3.訪問共享內存
                while(1)
                {
                    *p=i;
                    sleep(1);
                    i++;
                }
                
            }

            #include <stdio.h>
            #include <string.h>
            #include <stdlib.h>
            #include <unistd.h>
            #include <signal.h>
            #include <sys/shm.h>
            #include <sys/ipc.h>
            key_t key;
            int shmid;
            int *p;
            void deal(int s)
            {
                if(s==2)
                {
                    //4.卸載共享內存shmdt
                    shmdt(p);
                    exit(0);
                }
            }
            main()
            {
                signal(SIGINT,deal);    
                //1.創建共享內存shmget
                key=ftok(".",255);
                if(key==-1) printf("ftok error:%m\n"),exit(-1);
                
                shmid=shmget(key,4,0);
                if(shmid==-1) printf("get error:%m\n"),exit(-1);
                //2.掛載共享內存shmat
                p=shmat(shmid,0,0);
                if(p==(int*)-1) printf("at error:%m\n"),exit(-1);
                //3.訪問共享內存
                while(1)
                {        
                    sleep(1);
                    printf("%d\n",*p);
                }
            }
             3.內核共享隊列(有序)
                編程模型:
                  3.1.創建共享隊列/得到隊列msgget
                  3.2.使用隊列(發送消息msgsnd/接收消息msgrcv)
                  3.3.刪除隊列msgctl
            案例:
               A:創建共享隊列
                 int msgget(key_t,int);      
               B:發送消息
             int msgsnd(
                        int id,//消息隊列ID
                        const void *msg,//要發送消息
                        size_t len,//消息的長度
                        int flags//發送消息的方式0或者IPC_NOWAIT,建議為0 
                    );
               返回:
                   -1:失敗
                    0:成功 
                 第二個參數的消息有固定的格式
                    4字節:表示消息的類型
                    若干字節:消息內容。
                 第三個參數:
                    消息的大小,不包含類型的4個字節

            #include <unistd.h>
            #include <sys/ipc.h>
            #include <sys/msg.h>
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            struct msgbuf
            {
                long type;
                char data[32];
            };
            main()
            {
                key_t key;
                int msgid;
                int i;
                struct msgbuf msg;
                
                //1創建消息隊列
                key=ftok(".",200);
                if(key==-1) printf("ftok err:%m\n"),exit(-1);
                
                msgid=msgget(key,0/*IPC_CREAT|IPC_EXCL|0666*/);
                if(msgid==-1)printf("get err:%m\n"),exit(-1);
                //2構造消息
                    
                
            //3發送消息
                for(i=1;i<=10;i++)
                {
                    bzero(msg.data,sizeof(msg.data));
                    msg.type=1;
                    sprintf(msg.data,"MessageI:%d",i);
                    msgsnd(msgid,&msg,sizeof(msg.data),0);
                }
                for(i=1;i<=10;i++)
                {
                    bzero(msg.data,sizeof(msg.data));
                    msg.type=2;
                    sprintf(msg.data,"MessageII:%d",i);
                    
                    msgsnd(msgid,&msg,sizeof(msg.data),0);
                }
                //4刪除隊列
                
            //msgctl(msgid,IPC_RMID,0);
            }

            #include <unistd.h>
            #include <sys/ipc.h>
            #include <sys/msg.h>
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            struct msgbuf
            {
                long type;
                char data[32];
            };
            main()
            {
                key_t key;
                int msgid;
                int i;
                struct msgbuf msg;
                //1得到消息隊列
                key=ftok(".",200);
                if(key==-1) printf("ftok err:%m\n"),exit(-1);
                
                msgid=msgget(key,0);
                if(msgid==-1)printf("get err:%m\n"),exit(-1);
                //2構造消息
                    
                
            //3接收消息
                while(1)
                {
                    bzero(&msg,sizeof(msg));
                    msg.type=2;
                    msgrcv(msgid,&msg,sizeof(msg.data),2,0);
                    printf("%s\n",msg.data);
                }
            }
            三.基于socket文件的IPC
             socket文件的通信方式,比較重要,原因:網絡采用這種通信模型。
             兩種模型:
                對等模型
                C/S模型
             1.對等模型:
                1.建立socket:socket
             int socket(
                            int domain,//地址族的類型AF_UNIX AF_INET
                            int type,//支持的數據格式:流SOCK_STREAM/報文SOCK_DGRAM
                            int protocol);//支持的協議,建議為0 
                返回值:
                    成功返回文件描述符號。
                    失敗返回-1;
                2.綁定在地址上(文件目錄地址)URL(Universe Resource Location)
                  協議://路徑/文件名
                  file:///usr/bin/ls
                  http://192.168.0.72/index.php
                  struct sockaddr;
                  struct sockaddr_un;un=unix
                  struct sockaddr_in;in=internet
             int bind(int fd,//socket描述符號
                        struct sockaddr*addr,//綁定地址
                        socklen_t size);//地址長度
                3.接收數據
                  read/recv/recvfrom
                4.關閉socket

            #include <sys/socket.h>
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            #include <unistd.h>
            #include <linux/un.h>

            main()
            {
                int fd;
                int r;
                char buf[200];
                //1.建立socket
                fd=socket(AF_UNIX,SOCK_DGRAM,0);
                if(fd==-1) printf("socket err:%m\n"),exit(-1);
                printf("socket成功!\n");
                //2.構造本地文件地址
                struct sockaddr_un addr={0};
                addr.sun_family=AF_UNIX;
                memcpy(addr.sun_path,"my.sock",
                                strlen("my.sock"));
                
                //3.把socket綁定在地址上
                r=bind(fd,(struct sockaddr*)&addr,sizeof(addr));
                if(r==-1) printf("bind err:%m\n"),exit(-1);
                printf("地址綁定成功!\n");
                
                //4.接收數據
                while(1)
                {
                    bzero(buf,sizeof(buf));
                    r=read(fd,buf,sizeof(buf));
                    buf[r]=0;
                    printf("%s\n",buf);
                }    
                
                //5.關閉
                close(fd);
                //6.刪除socket文件
                unlink("my.sock");
                
            }
                1.建立socket:socket
                2.連接到目標:connect(可選)    
                3.發送數據:write/send/sendto
                4.關閉close

            #include <stdio.h>
            #include <stdlib.h>
            #include <sys/socket.h>
            #include <linux/un.h>
            #include <string.h>
            #include <unistd.h>
            main()
            {
                int fd;
                int r;
                char buf[100];
                struct sockaddr_un addr={0};
                //1.建立socket
                fd=socket(AF_UNIX,SOCK_DGRAM,0);
                //2.連接到指定的地址
                addr.sun_family=AF_UNIX;
                memcpy(addr.sun_path,"my.sock",
                        strlen("my.sock"));
                r=connect(fd,(struct sockaddr*)&addr,
                        sizeof(addr));
                //3.發送數據
                while(1)
                {
                    write(fd,"Hello!MaomaoYu!",
                        strlen("Hello!MaomaoYu!"));
                    sleep(1);    
                }
                //4.關閉
                close(fd);
            }

            #include <sys/socket.h>
            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            #include <unistd.h>
            //1.
            #include <netinet/in.h>
            #include <arpa/inet.h>

            main()
            {
                int fd;
                int r;
                char buf[200];
                //1.建立socket
                
            //2
                fd=socket(AF_INET,SOCK_DGRAM,0);
                if(fd==-1) printf("socket err:%m\n"),exit(-1);
                printf("socket成功!\n");
                //2.構造本地文件地址
                
            //3.
                struct sockaddr_in addr={0};
                addr.sin_family=AF_INET;
                addr.sin_port=htons(9999);
                addr.sin_addr.s_addr=
                        inet_addr("192.168.180.92");
                //3.把socket綁定在地址上
                r=bind(fd,(struct sockaddr*)&addr,sizeof(addr));
                if(r==-1) printf("bind err:%m\n"),exit(-1);
                printf("地址綁定成功!\n");
                
                //4.接收數據
                while(1)
                {
                    bzero(buf,sizeof(buf));
                    r=read(fd,buf,sizeof(buf));
                    buf[r]=0;
                    printf("%s\n",buf);
                }    
                
                //5.關閉
                close(fd);
                //6.刪除socket文件
                unlink("my.sock");
                
            }

            #include <stdio.h>
            #include <stdlib.h>
            #include <sys/socket.h>
            #include <string.h>
            #include <unistd.h>
            //1
            #include <netinet/in.h>
            #include <arpa/inet.h>
            main()
            {
                int fd;
                int r;
                //2
                struct sockaddr_in addr={0};
                //1.建立socket
                
            //3
                fd=socket(AF_INET,SOCK_DGRAM,0);
                //2.連接到指定的地址
                
            //4
                addr.sin_family=AF_INET;
                addr.sin_port=htons(9999);
                addr.sin_addr.s_addr
                    =inet_addr("192.168.180.92");
                
                r=connect(fd,(struct sockaddr*)&addr,
                        sizeof(addr));
                //3.發送數據
                write(fd,"Hello!Maomaochong!",
                    strlen("Hello!Maomaochong!"));
                //4.關閉
                close(fd);dd
            }
            2.C/S模型
               Server            Client
               建立socket:socket   建立socket:socket
               綁定地址:bind       建立連接:connect
               監聽:listen   
               接收:accept    
               read/write         read/write
               close             close
               
               int listen(int fd,int num);
                 0:監聽成功
                 -1:失敗
            int accept(int fd,
                    struct sockaddr*addr,//返回連接著的地址
                    socklen_t* len)//接收返回地址的緩沖長度
             返回: 
                 -1:接收失敗
                 >=0:對應客戶的文件描述符號 

            #include <stdio.h>
            #include <stdlib.h>
            #include <string.h>
            #include <unistd.h>
            #include <sys/socket.h>
            #include <linux/un.h>

            main()
            {
                int sfd;
                int cfd;
                struct sockaddr_un addr;
                int r;
                char buf[100];
                //1.建立socket
                sfd=socket(AF_UNIX,SOCK_STREAM,0);
                if(sfd==-1) printf("socket err:%m\n"),exit(-1);
                printf("建立socket成功!\n");
                
                //2.綁定地址
                bzero(&addr,sizeof(addr));
                addr.sun_family=AF_UNIX;
                memcpy(addr.sun_path,"cs.sock",
                    strlen("cs.sock")+1);
                r=bind(sfd,(struct sockaddr*)&addr,sizeof(addr));
                if(r==-1) printf("bind err:%m\n"),exit(-1);
                printf("bind成功!\n");
                
                //3.監聽
                r=listen(sfd,10);
                if(r==-1) printf("listen err:%m\n"),exit(-1);
                printf("listen成功!\n");
                
                //4.接收客戶
                cfd=accept(sfd,0,0);
                if(cfd==-1) printf("accept err:%m\n"),exit(-1);
                printf("建立連接者的狀態成功!\n");
                //5.接收這個客戶的數據
                while(1)
                {
                    r=read(cfd,buf,sizeof(buf));
                    if(r==0)
                    {
                        printf("連接者退出");
                        break;
                    }
                    if(r==-1)
                    {
                        printf("scoket故障!\n");
                        break;
                    }
                    buf[r]=0;
                    printf("::%s\n",buf);
                    write(cfd,"Hi",2);
                    
                }
                //6.關閉客戶
                close(cfd);
                //7.關閉整個socket
                close(sfd);
                
            }

            #include <stdio.h>
            #include <stdlib.h>
            #include <sys/socket.h>
            #include <linux/un.h>
            #include <string.h>
            #include <unistd.h>
            main()
            {
                int fd;
                int r;
                char buf[100];
                struct sockaddr_un addr={0};
                //1.建立socket
                
            //fd=socket(AF_UNIX,SOCK_DGRAM,0);
                fd=socket(AF_UNIX,SOCK_STREAM,0);
                //2.連接到指定的地址
                addr.sun_family=AF_UNIX;
                memcpy(addr.sun_path,"cs.sock",
                        strlen("cs.sock"));
                r=connect(fd,(struct sockaddr*)&addr,
                        sizeof(addr));
                //3.發送數據
                while(1)
                {
                    write(fd,"Hello!MaomaoYu!",
                        strlen("Hello!MaomaoYu!"));
                    read(fd,buf,100);
                    printf("%s\n",buf);
                    sleep(1);    
                }
                //4.關閉
                close(fd);
            }

            總結:
               共享內存
               共享隊列
               socket文件通信
            課堂練習:
               CS模型代碼
               CS模型把socket文件替換成IP地址

            課后作業:
               模仿課堂案例獨立完成      
                 1.共享內存
                 2.共享隊列
                 3.socket對等模型
                 4.socket的CS模型

            久久精品一区二区三区中文字幕| 久久福利资源国产精品999| 精品久久久久久无码中文字幕一区| 精品久久久久久无码专区 | 99精品久久久久久久婷婷| 久久人人爽人人爽AV片| 久久国产精品99国产精| 伊人久久成人成综合网222| 国产免费久久精品99久久| 久久精品亚洲一区二区三区浴池| 精品精品国产自在久久高清| 色偷偷88888欧美精品久久久 | 亚洲精品美女久久久久99小说| 久久国产福利免费| 国产成人精品久久一区二区三区av | 国产精品久久久久aaaa| 久久综合狠狠综合久久| 精品久久久久久国产三级| 久久这里只有精品18| 久久免费香蕉视频| 久久香蕉国产线看观看99| 国产精品美女久久久久网| 久久亚洲中文字幕精品一区| 久久精品国产91久久麻豆自制| 亚洲人AV永久一区二区三区久久 | 合区精品久久久中文字幕一区| 丁香五月网久久综合| 久久婷婷五月综合成人D啪| 久久无码AV一区二区三区| 国产精品va久久久久久久| 国内精品久久久久久久久电影网| 区久久AAA片69亚洲| 日韩欧美亚洲综合久久影院d3| 亚洲精品国产美女久久久| 久久影院综合精品| 99久久夜色精品国产网站| 久久乐国产综合亚洲精品| 色婷婷综合久久久久中文 | 精品国产乱码久久久久久1区2区| 久久综合亚洲色HEZYO社区| 色综合合久久天天给综看|