1.有名信号量
操作共享内存的步骤: ftok生成一个key值 ->通过key 用 smget 创建一组信号量(下标0,1区分),返回一个信号灯的ID -> 对信号灯的初始化 (struct sembuf 结构体成员的赋值 ,成员sem_op中-1 是申请信号量,+1是释放信号量)-> 用semop去申请或者释放信号量)->
 semctl 删除共享空间
1.创建:
semget
int semget(key_t key, int nsems, int semflg);
功能:创建一组信号量
参数:key:IPC对像的名字
nsems:信号量的数量
semflg:IPC_CREAT
返回值:成功返回信号量ID
               失败返回-1
2.销毁
semctl
int semctl(int semid, int semnum, int cmd, ...);
功能:向信号灯发送命令
参数:semid:信号等的ID
semnum:具体操作信灯的编号
           cmd: IPC_RMID    删除信号灯
                       SETVAL      设置信号量的值
返回值:成功返回0;失败返回-1;
初始化:
 union semun {
             int              val;    /* Value for SETVAL */
             struct semid_ds *buf;    /* Buffer for IPC_STAT, IPC_SET */
             unsigned short  *array;  /* Array for GETALL, SETALL */
             struct seminfo  *__buf;  /* Buffer for IPC_INFO
                                         (Linux-specific) */
         };
3.申请信号量 / 释放信号量
semop
int semop(int semid, struct sembuf *sops, size_t nsops);
功能:对信号量完成操作
参数:semid:信号灯的ID
sops:信号量操作的数组的首地址
nsops:数组元素的个数
返回值:成功返回0;失败返回-1;
unsigned short sem_num;  /* semaphore number */        操作信号量的下标
          short          sem_op;   /* semaphore operation */     具体对信号量的操作(申请:-1  释放:+1)
          short          sem_flg;  /* operation flags */         SEM_UNDO
2. 网络(数据传输,数据共享):
1.网络协议模型
OSI协议模型:
       应用层:实际发送的数据
        表示层:发送的数据是否加密
        会话层:是否建立会话连接
        传输层:数据的传输方式(数据报,流式)
        网络层:数据的路由(如何从一个局域网到达另外一个局域网)    IP地址
        数据链路层:局域网下如何通信
        物理层:物理介质的连接
TCP/IP协议模型
         应用层:传输的数据
          传输层:传输的方式
          网络层:数据如何从一台主机到达另一台主机
          网络接口层:物质介质的连接
应用层: HTTP  超文本传输协议
                hTTPS
                FTP     文件传输协议
                TFTP   简单文本传输协议
                SMTP  邮件传输协议
                MQTT  
                TELNET
 传输层:
         UDP     用户数据报协议
                 特点:
                     1.实现机制简单
                     2.资源开销小
                     3.不安全不可靠
        TCP     传输控制协议
                 特点:
                     1.实现机制复杂(三次握手)
                     2.资源开销大
                     3.安全可靠(四次挥手)
    网络层:
         IPv4
        IP地址:唯一标识网络中一台主机的标号
         IP地址:网络位 + 主机位
         子网掩码:用来标识IP地址的网络位和主机位
                 子网掩码是1的部分表示IP地址的网络位
                 子网掩码是0的部分表示IP地址的主机位
         网段号:网络位不变,主机位全为0,表示网段号
         广播地址:网络位不变,主机位全为1,表示广播地址
        IP地址类型:
         A类
             1.0.0.0 - 126.255.255.255
             子网掩码:255.0.0.0
             管理超大规模网络
             10.0.0.0 - 10.255.255.255 
        B类
             128.0.0.0 - 191.255.255.255
             子网掩码:255.255.0.0 
             管理大中规模型网络
             172.16.0.0 - 172.31.255.255
        C类
             192.0.0.0 - 223.255.255.255
             子网掩码:255.255.255.0
             管理中小规模型网络 
             192.168.0.0 - 192.168.255.255
        D类
             224.0.0.0 - 239.0.0.0
             用于组播
        E类
             240.0.0.0 - 255.255.255.255 
             用于实验
2.UDP编程
socket套接字编程 : socket 创建通信的文件描述符 -> struct sockaddr_in 结构体成员的赋值( inet_addr 将字符串地址转换为内存地址  ,htons 将本地字节序转换为网络的大端字节序) ->
 sendto 向目标地址发送数据信息
1.发端:
socket
        int socket(int domain, int type, int protocol);
         功能:
             创建一个用来通信的文件描述符
         参数:
             domain:使用的协议族 AF_INET (IPv4协议族)
             type:套接字类型
                 SOCK_STREAM:流式套接字
                 SOCK_DGRAM:数据报套接字
                 SOCK_RAW:原始套接字
             protocol:协议
                 默认为0 
         返回值:
             成功返回文件描述符
             失败返回-1 
sendto
        ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
                       const struct sockaddr *dest_addr, socklen_t addrlen);
         功能:
             利用套接字向指定地址发送数据信息 
         参数:
             sockfd:套接字文件描述符
             buf:发送数据空间首地址
             len:发送数据的长度
             flags:属性默认为0 
             dest_addr:目的地址信息存放的空间首地址
             addrlen:目的地址的长度
         
         struct sockaddr_in {
             sa_family_t    sin_family; /* address family: AF_INET */
             in_port_t      sin_port;   /* port in network byte order */
             struct in_addr sin_addr;   /* internet address */
         };
        /* Internet address. */
         struct in_addr {
             uint32_t       s_addr;     /* address in network byte order */
         };
                   
         返回值:
             成功返回实际发送字节数
             失败返回-1 
inet_addr:
        in_addr_t inet_addr(const char *cp);
         功能:  
             将字符串IP地址转换为内存中的IP地址 
htons
        uint16_t htons(uint16_t hostshort);
         功能:
             将本地字节序转换为网络的大端字节序
eg:
int  main(void)
{int sockfd = 0;struct sockaddr_in recvaddr; //定义目的地址信息存放的结构体变量char tmpbuff[1024] = {0};char tm[1024] = {0};ssize_t nsize = 0;ssize_t msize = 0;int len = 0;fgets(tmpbuff,sizeof(tmpbuff),stdin);/*创建用来通信的UDP套接字 */sockfd = socket(AF_INET, SOCK_DGRAM, 0);   //创建一个用来通信的文件描述符if(sockfd == -1){perror("fail to socket");return -1;}/* 对接收方地址赋值 */recvaddr.sin_family = AF_INET;recvaddr.sin_port = htons(50000);   //将本地字节序转换为网络的大端字节序recvaddr.sin_addr.s_addr = inet_addr("192.168.136.1"); //将字符串IP地址转换内存中的ip地址len = sizeof(recvaddr);/*发送信息*/nsize = sendto(sockfd, tmpbuff, strlen(tmpbuff), 0, (struct sockaddr *)&recvaddr, sizeof(recvaddr)); //利用套接字向指定地址发送数据信息//套接字文件描述符,发送数据空间地址,地址大小,属性默认0,目的地地址信息存放的空间地址(强制转换),地址大小if (-1 == nsize){perror("fail to sendto");return -1;}printf("已发送%ld个字节!!!\n",nsize);memset(tmpbuff,0,sizeof(tmpbuff));msize= recvfrom(sockfd,tm,sizeof(tm),0,(struct sockaddr *)&recvaddr,&len);puts(tm);close(sockfd);return 0;
}