• <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
            struct  sembuf 
            {
                int sem_num;//下標(biāo)
                int sem_op;
                int sem_flg;//建議為0.
            }一.信號量(同步)
             1.回顧:
               一個進程控制另外一個進程.
               邏輯變量+pause/sleep+信號
             2.信號量(semaphore)信號燈
              三個數(shù)據(jù):紅燈/綠燈/黃燈    
                    60   90   10
              信號量是共享內(nèi)存整數(shù)數(shù)組.根據(jù)需要定義指定的數(shù)組長度
              信號量就是根據(jù)數(shù)組中的值,決定阻塞還是解除阻塞
             
             3.編程
               3.1.創(chuàng)建或者得到信號量     semget
               3.2.初始化信號量中指定下標(biāo)的值 semctl
               3.3.根據(jù)信號量阻塞或者解除阻塞 semop
               3.4.刪除信號量         semctl
            案例:
               A:             B
               創(chuàng)建信號量        得到信號量
               初始化信號量      
               根據(jù)信號量阻塞     解除阻塞
               刪除信號量       
                
               semget函數(shù)說明
            int semget(key_t key,
                    int nums,//信號量數(shù)組個數(shù)
                    int flags);//信號量的創(chuàng)建標(biāo)記
                                            
            //創(chuàng)建IPC_CREAT|IPC_EXCL|0666
                                            
            //打開0
              返回:  -1:失敗
                  >=0:成功返回信號量的ID
            int semop(
                    int semid,//信號量ID
                    struct sembuf *op,//對信號量的操作.操作可以是數(shù)組多個
                    size_t nums,//第二個參數(shù)的個數(shù)
                );
              返回:
                 -1:時失敗
                  0:成功 
            int semctl(int semid,
                        int nums,//對IPC_RMID無意義
                        int cmd,//SETVAL  IPC_RMID
                        );//對IPC_RMID無意義
              sem_op:
                 前提條件信號量是unsigned short int;
                 不能<0.
                 -:夠減,則semop馬上返回,不夠減,則阻塞.
                 +:執(zhí)行+操作
                 0:判定信號量>0,則阻塞,直到為0
               控制進程的搭配方式:
                  +(解除阻塞) -(阻塞)
                  0(阻塞)     -(解除阻塞)
            #include <stdio.h>
            #include <unistd.h>
            #include <stdlib.h>
            #include <sys/ipc.h>
            #include <sys/sem.h>
            //2.1.定義一個聯(lián)合體
            union semun {
                int    val;
                struct semid_ds *buf;
                unsigned short  *array;
                struct seminfo  *__buf;
            };

            main()
            {
                key_t key;
                int semid;    //信號量ID
                union  semun v;//2.2.定義初始化值
                int r;
                struct sembuf op[1];
                //1.創(chuàng)建信號量
                key=ftok(".",99);
                if(key==-1) printf("ftok err:%m\n"),exit(-1);
                
                //semid=semget(key,1/*信號量數(shù)組個數(shù)*/,
                
            //        IPC_CREAT|IPC_EXCL|0666);
                        
                semid=semget(key,1,0);//得到信號量
                if(semid==-1) printf("get err:%m\n"),exit(-1);
                
                printf("id:%d\n",semid);
                //2.初始化信號量
                v.val=2;
                r=semctl(semid,0,SETVAL,v);//2.3設(shè)置信號量的值
                if(r==-1) printf("初始化失敗!\n"),exit(-1);

                //3.對信號量進行阻塞操作
                
            //3.1.定義操作
                op[0].sem_num=0;//信號量下標(biāo)
                op[0].sem_op=-1;//信號量操作單位與類型
                op[0].sem_flg=0;
                while(1)
                {
                    r=semop(semid,op,1);
                    printf("解除阻塞!\n");
                }
                
                //4.刪除(可以不刪除)
            }

            #include <stdio.h>
            #include <unistd.h>
            #include <stdlib.h>
            #include <sys/ipc.h>
            #include <sys/sem.h>
            //2.1.定義一個聯(lián)合體
            union semun {
                int    val;
                struct semid_ds *buf;
                unsigned short  *array;
                struct seminfo  *__buf;
            };

            main()
            {
                key_t key;
                int semid;    //信號量ID
                union  semun v;//2.2.定義初始化值
                int r;
                struct sembuf op[2];
                //1.創(chuàng)建信號量
                key=ftok(".",99);
                if(key==-1) printf("ftok err:%m\n"),exit(-1);
                
                        
                semid=semget(key,1,0);//得到信號量
                if(semid==-1) printf("get err:%m\n"),exit(-1);
                
                printf("id:%d\n",semid);        
                //3.對信號量進行阻塞操作
                
            //3.1.定義操作
                op[0].sem_num=0;//信號量下標(biāo)
                op[0].sem_op=1;//信號量操作單位與類型
                op[0].sem_flg=0;
                op[1].sem_num=0;//信號量下標(biāo)
                op[1].sem_op=1;//信號量操作單位與類型
                op[1].sem_flg=0;
                while(1)
                {
                    r=semop(semid,op,2);
                    sleep(1);
                }
                
                //4.刪除(可以不刪除)
                
            //semctl(semid,0,IPC_RMID);
            }

            二.網(wǎng)絡(luò)
             1.基礎(chǔ)(ip)
              1.1.網(wǎng)絡(luò)工具
                ping
                ping ip地址
                ping -b ip廣播地址
                ifconfig -a    
                
                netstat -a
                netstat -u
                netstat -t
                netstat -x
                netstat -n
                
                route
                lsof
              1.2.網(wǎng)絡(luò)的基本概念
                網(wǎng)絡(luò)編程采用socket模型.
                網(wǎng)絡(luò)通信本質(zhì)也是進程之間的IPC。
                   是不同主機之間。
                
                識別主機:4字節(jié)整數(shù):IP地址
                識別進程:2字節(jié)整數(shù):端口號
                  
                IP地址的表示方法: 內(nèi)部表示:4字節(jié)整數(shù) 
                           外部表示:數(shù)點字符串
                                結(jié)構(gòu)體
                  1 2 3 4  分段表示,每個段使用.分割
                  "192.168.0.26"

                ip地址的轉(zhuǎn)換:  

            struct  sockaddr_in
                {
                    int                         sin_family;
                    in_port_t             sin_port;
                    struct in_addr     sin_addr;
                    
                }
             struct in_addr
                {
                    in_addr_t  s_addr;
                }    
               //總結(jié):
                  IP地址的表示
                    字符串表示"192.168.0.26"
                    整數(shù)表示:in_addr_t;
                    字結(jié)構(gòu)表示struct in_addr;
                  連接點:endpoint
             struct sockaddr_in
                {
                    in_port_t                 sin_port;
                    struct in_addr       sin_addr;
                };
             1.3.IP地址的轉(zhuǎn)換
               inet_addr   //把字符串IP轉(zhuǎn)換為二進制整數(shù)IP(網(wǎng)絡(luò)字節(jié)序)
               inet_aton  //把字符串IP轉(zhuǎn)換為struct in_addr;(網(wǎng)絡(luò)字結(jié)序) 
               #inet_network//把字符串IP轉(zhuǎn)換為二進制整數(shù)IP(本地字節(jié)序)
               inet_ntoa  //把結(jié)構(gòu)體struct in_addr轉(zhuǎn)換為字符串IP
               
              4個本地主機字節(jié)序與網(wǎng)絡(luò)序轉(zhuǎn)換函數(shù):
              h表示主機字節(jié)序,n表示網(wǎng)絡(luò)字節(jié)序,s表示兩個2字節(jié),l表示4個字節(jié)
               uint16_t htons(uint16_t)
               uint32_t htonl(uint32_t)
               uint16_t ntohs(uint16_t)
               uint32_t ntohl(uint32_t)
               ps:所以發(fā)送時候,端口轉(zhuǎn)換可以用htons,而ip可以用htonl

            #include <stdio.h>
            #include <sys/socket.h>
            #include <netinet/in.h>
            #include <arpa/inet.h>
            main()
            {
                /*
                in_addr_t  nip=192<<24 | 168 <<16 | 0<<8  | 26;
                char  *ip="192.168.0.26";
                //把整數(shù)轉(zhuǎn)換為字符串inet_ntoa
                struct in_addr sip;
                int myip;
                
                sip.s_addr=nip;
                
                printf("nip:%u\n",nip);
                
                printf("%s\n",inet_ntoa(sip));
                
                myip=inet_addr(ip);
                printf("%u\n",myip);
                
                printf("%hhu.%hhu.%hhu.%hhu\n",    myip>>24 & 255,
                                        myip>>16 & 255,
                                        myip>>8  & 255,
                                        myip>>0  & 255);
                
            */
                /*
                char ip[4]={192,168,0,26};
                printf("%d\n",*(int*)ip);
                
            */
                char *ip="10.45.8.1";
                struct in_addr addr;
                in_addr_t net;
                in_addr_t host;
                struct in_addr tmp;
                
                inet_aton(ip,&addr);
                net=inet_lnaof(addr);
                host=inet_netof(addr);
                
                tmp.s_addr=net;
                
                printf("%s\n",inet_ntoa(tmp));
                
                tmp.s_addr=host;
                printf("%s\n",inet_ntoa(tmp));
            }
            1.4.IP地址的意義 
               IP地址的位表達不同意義:
                 IP地址組建網(wǎng)絡(luò):網(wǎng)絡(luò)標(biāo)識/主機標(biāo)識
                      網(wǎng)絡(luò)     主機
               A類     7         24    網(wǎng)絡(luò)少  主機
               B類     14         16      
               C類     21          8 
               D類     組播 
               E類     沒有使用
               
              1.5.計算機系統(tǒng)中的網(wǎng)絡(luò)配置
               /etc/hosts文件  配置IP,域名,主機名
                  gethostbyname
                  gethostbyaddr
               /etc/protocols文件  配置系統(tǒng)支持的協(xié)議
               /etc/services文件 配置服務(wù)   
               get***by***;   
               gethostbyname   
               getprotobyname

            #include <stdio.h>
            #include <netdb.h>
            main()
            {
                struct hostent *ent;
                /*打開主機配置數(shù)據(jù)庫文件*/
                sethostent(1);
                while(1)
                {
                    ent=gethostent();
                    if(ent==0) break;
                    
                    printf("主機名:%s\t",ent->h_name);
                    printf("IP地址:%hhu.%hhu.%hhu.%hhu\t",
                            ent->h_addr[0],
                            ent->h_addr[1],
                            ent->h_addr[2],
                            ent->h_addr[3]);
                    printf("別名:%s\n",ent->h_aliases[0]);
                }
                endhostent();
            }

            #include <stdio.h>
            #include <netdb.h>
            main()
            {
                struct hostent *ent;
                ent=gethostbyname("bbs.tarena.com.cn");
                //printf("%s\n",ent->h_aliases[0]);
                printf("%hhu.%hhu.%hhu.%hhu\n",
                    ent->h_addr_list[0][0],
                    ent->h_addr_list[0][1],
                    ent->h_addr_list[0][2],
                    ent->h_addr_list[0][3]);
            }

            #include <stdio.h>
            #include <netdb.h>
            #include <sys/utsname.h>
            main()
            {
                struct protoent *ent;
                struct utsname name;
                ent=getprotobyname("tcp");
                printf("%d\n",ent->p_proto);
                
                uname(&name);
                printf("%s\n",name.machine);
                printf("%s\n",name.nodename);
                printf("%s\n",name.sysname);
                printf("%s\n",name.domainname);
            }
            2.TCP/UDP編程
               對等模型:AF_INET   SOCK_DGRAM    0:UDP
               C/S 模型:AF_INET  SOCK_STREAM   0:TCP
              2.0.網(wǎng)絡(luò)編程
                ISO的7層模型:
                   物理層     
                   數(shù)據(jù)鏈路層   數(shù)據(jù)鏈路層(數(shù)據(jù)物理怎么傳輸)
                   網(wǎng)絡(luò)層     IP層   (數(shù)據(jù)的傳輸方式)
                   傳輸層     傳輸層   (數(shù)據(jù)傳輸?shù)慕Y(jié)果)     
                   會話層     應(yīng)用層   (數(shù)據(jù)傳遞的含義)
                   表示層
                   應(yīng)用層
                     
              2.1.UDP編程的數(shù)據(jù)特點
                UDP采用對等模型SOCK_DGRAM
                socket            socket:socket
                綁定IP地址bind        連接目標(biāo)(可選)  conncect
                read/recv/recvfrom      發(fā)送數(shù)據(jù) write/send/sendto
                關(guān)閉close   
            案例:
              A:                    B
               接收用戶的數(shù)據(jù)         發(fā)送數(shù)據(jù)
               打印數(shù)據(jù)與發(fā)送者IP     接收數(shù)據(jù)并打印
               返發(fā)一個信息       

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

            main()
            {
                int fd;//socket描述符號
                struct sockaddr_in ad;//本機的IP地址
                char buf[100];//接收數(shù)據(jù)緩沖
                
                struct sockaddr_in ad_snd;//發(fā)送者IP地址
                socklen_t len;//發(fā)送者IP的長度
                int r;
                
                fd=socket(AF_INET,SOCK_DGRAM,17);
                if(fd==-1) printf("socket:%m\n"),exit(-1);
                printf("建立socket成功!\n");
                
                ad.sin_family=AF_INET;
                ad.sin_port=htons(11111);
                inet_aton("192.168.180.92",&ad.sin_addr);
                r=bind(fd,(struct sockaddr*)&ad,sizeof(ad));
                if(r==-1) printf("bind err:%m\n"),exit(-1);
                printf("綁定成功!\n");
                
                while(1)
                {
                    len=sizeof(ad_snd);
                    r=recvfrom(fd,buf,sizeof(buf)-1,0,
                            (struct sockaddr*)&ad_snd,&len);
                    if(r>0){
                        buf[r]=0;
                        printf("發(fā)送者IP:%s,端口:%hu,數(shù)據(jù):%s\n",
                            inet_ntoa(ad_snd.sin_addr),
                            ntohs(ad_snd.sin_port),buf);
                        sendto(fd,"古怪!",strlen("古怪!"),0,
                        (struct sockaddr*)&ad_snd,sizeof(ad_snd));
                    }
                    if(r==0)
                    {
                        printf("關(guān)閉!\n");            
                        break;
                    }
                    if(r==-1)
                    {
                        printf("網(wǎng)絡(luò)故障!\n");            
                        break;
                    }
                }
                
                close(fd);
            }
             總結(jié):
                1.問題:
                  connect + send  == sendto
                2.問題:
                  recvfrom的作用不是專門從指定IP接收
                  而是從任意IP接收數(shù)據(jù),返回發(fā)送數(shù)據(jù)者的IP
                3.問題:
                  為什么要bind,bind主要目的告訴網(wǎng)絡(luò)發(fā)送數(shù)據(jù)的目標(biāo).
                  是否一定綁定才能發(fā)送數(shù)據(jù)?
                  否:只要知道你的IP與PORT,就能發(fā)送數(shù)據(jù).
                4.問題:
                  為什么發(fā)送者沒有綁定IP與端口,他也有端口?
                  底層網(wǎng)絡(luò)驅(qū)動,幫我們自動生成IP與端口.
                5.缺陷:
                  接收方不區(qū)分發(fā)送者的.  
                    
             send函數(shù)  
             sendto函數(shù)
            int sendto(
                    int fd,//socket描述符號
                    const void *buf,//發(fā)送的數(shù)據(jù)緩沖
                    size_t size,//發(fā)送的數(shù)據(jù)長度
                    int flags,//發(fā)送方式MSG_NOWAIT MSG_OOB
                    const struct sockaddr *addr,//發(fā)送的目標(biāo)的IP與端口
                    socklen_t len//sockaddr_in的長度
                );
               返回:
                 -1:發(fā)送失敗
                 >=0:發(fā)送的數(shù)據(jù)長度
             recv函數(shù)
             recvfrom函數(shù) 
            int recvfrom(
                    int fd,
                    void *buf,
                    size_t size,
                    int flags,
                    struct sockaddr*addr,//返回發(fā)送者IP與端口
                    socklen_t *len);//輸入返回IP的緩沖大小,返回實際IP的大小
             2.2.TCP編程的數(shù)據(jù)特點
              2.3.TCP服務(wù)器的編程
             3.TCP的服務(wù)器編程模型
             4.IP協(xié)議與處理(SOCK_RAW,SOCK_PACKET)
             5.pcap編程
             6.HTTP協(xié)議與網(wǎng)頁搜索
             
            作業(yè):
              1.重新編寫UDP網(wǎng)絡(luò)通信 
              2.使用gethostbyname的得到bbs.tarena.com.cn
            丁香五月综合久久激情| 99久久免费国产精品| www性久久久com| 国内精品久久久久影院日本| 伊人久久大香线蕉成人| 午夜精品久久久久成人| 久久无码人妻精品一区二区三区| 久久国产午夜精品一区二区三区| 激情伊人五月天久久综合| 一本色综合久久| 精品熟女少妇AV免费久久| 午夜精品久久久久久久久| 久久精品国产网红主播| 国内精品久久久久久久久| 久久亚洲熟女cc98cm| 国产亚洲色婷婷久久99精品| 日产精品久久久一区二区| 一本大道久久a久久精品综合| 国产69精品久久久久9999| 久久99精品久久久久久久不卡 | 亚洲第一永久AV网站久久精品男人的天堂AV | 国产—久久香蕉国产线看观看| 久久99国产精一区二区三区| 国产精品日韩欧美久久综合| 色综合久久88色综合天天| 亚洲第一极品精品无码久久| 精品人妻久久久久久888| 大蕉久久伊人中文字幕| 亚洲日韩欧美一区久久久久我| 精品国产乱码久久久久软件| 久久久一本精品99久久精品88| 久久精品国产亚洲AV嫖农村妇女| 国产精品久久网| 亚洲&#228;v永久无码精品天堂久久 | 99re这里只有精品热久久| 66精品综合久久久久久久| 亚洲国产日韩综合久久精品| av无码久久久久久不卡网站| 久久影视综合亚洲| 97久久超碰国产精品2021| 久久国产影院|