C语言--day30

消息队列

  • System V提供的IPC对象,用于进程间通信

  • 可以发送指定消息类型的消息,可用于设置消息的优先级

    查看IPC对象的命令:
    ipcs -a 查询共享内存,信号量集,消息队列
    ipcrm -s 删除信号量集
    -m 删除共享内存
    -q 删除消息队列
    ipcrm -m shmid
    ipcrm -M shmkey
    ipcrm -q msgid
    ipcrm -Q msgkey

获取IPC对象key值:ftok( )

复制代码
key_t ftok(const char *pathname, int proj_id);
功能:获取IPC对象的key值
参数:
	pathname:路径名
	proj_id:工程id
返回值:
	成功:key值
	失败:-1

创建消息队列:msgget( )

复制代码
 int msgget(key_t key, int msgflg);
功能:创建消息队列并获得一个消息队列的id
参数:
	key:IPC对象key值
	msgflg:操作方式 :IPC_CREAT | 0664
返回值:
	成功:id
	失败:-1

发送消息:msgsnd()

复制代码
int msgsnd(int msqid, const void *msgp, size_t msgsz, int msgflg);
功能:向消息队列发送消息
参数:
	msqid:消息队列id
	msgp:发送的消息体
	msgsz:消息体中的正文大小
	msgflg:0 默认方式发送
成功:
	成功:0
	失败:-1
	
           struct msgbuf {
               long mtype;       /* message type, must be > 0 */
               char mtext[1];    /* message data */
           };

接收消息:msgrcv()

复制代码
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp,int msgflg);
功能:从消息队列接收消息
参数:	
	msqid:消息队列id
	msgp:存放消息体的空间地址
	msgsz:消息体正文大小
	msgtyp:接收的消息类型
		0 :按顺序收
		>0 : mtype 接收指定mtype的消息
		<0 :接收<=|mtype |的消息:-100: <=100
	msgflg:0 默认方式接收
返回值:
	成功:返回实际收到的消息体正文的大小
	失败:-1

删除消息队列:msgctl()

复制代码
int msgctl(int msqid, int cmd, struct msqid_ds *buf);
功能:对消息队列执行操作
参数:
	msqid:消息队列id
	cmd:
		IPC_STAT :获取状态
		IPC_SET:设置状态
		IPC_RMID:删除
	buf :
		删除:NULL
返回值
	成功:0
	失败:-1

共享内存

  • 进程间效率最高的通信方式
  • 原因:使用内存映射技术,减少了读写数据时反复数据拷贝带来的时间消耗

创建共享内存:shmget

复制代码
int shmget(key_t key, size_t size, int shmflg);
功能:创建共享内存并获得共享内存的id
参数:
	key:IPC对象的key值
	size:创建的共享内存的大小,向上取整到PAGE_SIZE(4096)整数倍
	shmflg: 创建方式
		IPC_CREAT | 0664
返回值:
	成功:共享内存的id
	失败:-1

建立内存映射shmat

复制代码
void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:建立共享内存和用户进程空间的映射
参数:
	shmid:共享内存id
	shmaddr:映射的用户空间首地址
		NULL:由操作系统自己分配用户空间
	shmflg:对共享内存的读写可执行权限
		SHM_EXEC: 可执行权限
		SHM_RDONLY:只读权限
		!SHM_RDONLY : 读写权限

解除内存映射shmdt

复制代码
int shmdt(const void *shmaddr);
功能:解除共享内存和用户空间的映射关系
参数:
	shmaddr:用户空间首地址
返回值:
	成功:0
	失败:-1

删除共享内存shmctl

复制代码
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:操作共享内存
参数:
	shmid:共享内存的id
	cmd:
		IPC_STAT :获取状态
		IPC_SET:设置状态
		IPC_RMID:删除
	buf :删除NULL
返回值:
	成功:0
	失败:-1

信号量集

  • 信号量数组
  • 信号量集:实现进程间同步

Linux网络编程

  • 网络:不同主机,进程间通信

网络基础

OSI七层模型
  • OSI模型: open system interconnect 理论模型 1977 国际标准化组织 各种不同体系结构的计算机能在世界范围内互联成网

    应用层:要传输的数据信息,如文件传输,电子邮件等
    表示层:数据加密,解密操作,压缩,解压缩
    会话层:建立数据传输通道
    传输层:传输的方式 UDP TCP 端口号
    网络层:实现数据路由 路由器 ip
    数据链路层:封装成帧,点对点通信(局域网内通信),差错检测 交换机 ARP
    物理层:定义物理设备标准,比如网线,光纤等传输介质 比特流 bit 0 1

TCP/IP模型
复制代码
    4层模型
    应用层(应用层、表示层、会话层):
              HTTP:超文本传输协议
              HTTPS:超文本传输协议(加密)
              FTP :文件传输协议
              TFTP:简单文件传输协议
              MQTT:消息队列遥测传输协议(物联网)
              自定义协议
    传输层:
              UDP:用户数据报协议
              TCP:传输控制协议
    网络层:
             IP协议
             IPv4/IPv6
    网络接口层(数据链路层、物理层):
             ARP:地址解析协议(IP地址转MAC地址)
             RARP:逆地址解析协议(MAC地址转IP地址)

    5层模型
    应用层(应用层、表示层、会话层):
    传输层:
    网络层:
    数据链路层:
    物理层:
IP协议
IP地址
  • 192.168.0.103 --->点分十进制 ---->>人看
  • IPv4 --->>32位保存的IP地址 11000000 10101000 00000000 01100111
  • IPv6 --->>128位保存IP地址 -->解决IP地址不够用的问题
  • 192.168.0.103 网络位+主机位
  • 子网掩码:255.255.255.0 1111 1111 1111 1111 1111 1111 0000 0000
  • 网络位(网段):表示当前主机所在的网段。子网掩码为1的位为网络位
  • 主机位:是当前网段的第几台主机。子网掩码为0的位为主机位
  • 网段号:192.168.0
几个特殊的IP地址:
复制代码
 	网段号:
 			IP地址网络位不变,主机位全为0,则为该IP地址的网段号
 			192.168.1.3
 			255.255.0.0
 			192.168.0.0
 			位于
 			192.168.1.0 网段内(网段内的IP能直接通信)
 	广播号:
 		192.168.0.255
 	    192.168.1.255
 		IP地址网络位不变,主机位全为1,则为该IP地址的广播号
 		192.168.1.3
 		255.255.255.0
 		广播号:
 		192.168.1.255(向广播号发送信息,所有局域网内IP都能收到此信息)
 		
 		feiQ VNC
 		192.168.1.255
 	网关地址:
 	    192.168.1.1
IP地址的划分:
复制代码
     (1)A类地址: 
            范围:1.0.0.0 - 126.255.255.255 
            子网掩码:255.0.0.0 126*2^24
            用于管理大规模网络 
            私有IP地址:10.0.0.0 - 10.255.255.255    
    (2)B类地址:
 			范围:128.0.0.0 - 191.255.255.255
 			子网掩码:255.255.0.0         2^16
 			管理大中规模网络
 			
 			私有IP地址:172.16.0.0 - 172.31.255.255
 		
 	(3)C类地址:
 			范围:192.0.0.0 - 223.255.255.255
 			子网掩码:255.255.255.0        2^8
 			管理中小规模网络
 			
 			私有IP地址:192.168.0.0 - 192.168.255.255
 			
 	(4)D类地址:
 			224.0.0.0 - 239.255.255.255
 			组播和广播使用
 			
 	(5)E类地址:
 			240.0.0.0 - 255.255.255.254
 			用来进行实验
 
 	公有IP:由电信公司直接分配,并需要付费的IP地址, 可以直接访问internet
 	私有IP:不能直接访问internet的ip地址
    127.0.0.0   回环地址
端口号
  • 定义:区分同意主机上的不同网络进程
16位的数值 0-65535 分类:
  1. 任何TCP/IP实现所提供的服务都用1-1023之间的端口号。 http : 80、8080 FTP: 20/21 TFPT: 69 HTTPS: 443 MQTT :1883
  2. 端口号从1024-49151是被注册的端口号,被IANA指定为特殊服务使用
  3. 从49152-65535是动态或私有端口号
网络协议栈
网络配置
  • ifconfig :查看Linux下主机的IP地址相关信息
  • ping IP地址/域名 :检查当前主机和目标主机是否网络联通
配置过程
  1. 虚拟机-->>设置-->>网络适配器--->>桥接模式
  2. 编辑-->>虚拟网络编辑器-->>更改设置-->>VMnet0设置为桥接模式-->>桥接到Windows正在上网的网卡-->>应用---->>确定
  3. 修改配置文件 sudo vim /etc/network/interfaces
  4. 重启网络服务 sudo /etc/init.d/networking restart

UDP协议

传输层协议:
UDP(user datagram protocol) :用户数据报协议

C/S和B/S模型

网络编程模型: C/S:Client/Server 客户端/服务器

  • 客户端是一个专用客户端
  • 客户端和服务端程序都需实现
  • 客户端和服务端都可以保存资源

B/S: Browser/Server 浏览器/服务器

  • 客户端是一个通用的客户端,只需要维护服务端
  • 一般都是用HTTP协议
  • 主要资源都在服务端
UDP的特点
  • 面向数据包
  • 不需要建立连接
  • 尽最大可能交付,不安全不可靠
  • UDP机制简单,实时性高,效率高
UDP编程
  • 套接字:系统为应用层提供的网络通信端口,本质是文件描述符
  • 创建套接字:socket

int socket(int domain, int type, int protocol)

  • 功能:创建一个套接字
  • 参数:
  • domain:使用的协议族
  • AF_INET: IPv4
  • AF_INET6:IPv6
  • type:传输方式
  • SOCK_STREAM :TCP
  • SOCK_DGRAM:UDP
  • 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);

  • 功能:发送UDP的数据包
  • 参数:
  • sockfd:套接字
  • buf:发送数据的首地址
  • len:发送的字节数
  • flags:0 默认方式发送
  • dest_addr:接收方(服务端)的地址信息的指针
  • addrlen:接收方地址的大小
  • 返回值:
  • 成功:实际发送的字节数
  • 失败:-1
cs 复制代码
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 */
};
主机字节序转网络字节序short类型:htons
cs 复制代码
主机字节序:小端 host
网络字节序:大端 network

uint32_t htonl(uint32_t hostlong); 主机转网络
uint16_t htons(uint16_t hostshort); 主机转网络
uint32_t ntohl(uint32_t netlong); 网络转主机
uint16_t ntohs(uint16_t netshort); 网络转主机

h:host
n:net
l:long
s:short
将字符串IP地址转成整形ip地址:inet_addr
cs 复制代码
in_addr_t inet_addr(const char *cp);
    功能:将字符串IP地址转换成二进制IP地址形式
char *inet_ntoa(struct in_addr in);
    功能:将二进制ip转换成字符串
绑定地址信息:bind

int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen)

  • 功能:绑定套接字和主机的IP、端口号
  • 参数:
  • sockfd:套接字
  • addr:当前主机的地址信息的变量指针
  • addrlen:地址变量的大小
  • 返回值:
  • 成功:0
  • 失败:-1
接收UDP数据recvfrom

ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,
struct sockaddr *src_addr, socklen_t *addrlen);

  • 功能:从UDP套接字接收数据
  • 参数:
  • sockfd:套接字
  • buf:存储数据的空间首地址
  • len:希望接收到的数据长度
  • flags:0 默认方式
  • src_addr:保存发送方地址的变量指针
  • addrlen:保存地址的变量大小的指针
  • 返回值:
  • 成功:返回实际收到的字节数
  • 失败:-1
UDP头部

|-----------|------------|
| 源端口号(2字节) | 目标端口号(2字节) |
| 长度(2字节) | 校验和(2字节) |

wireshark抓包工具

  • 作用:抓取当前主机经过网卡的网络数据,从而分析和追踪网络问题

  • 安装:sudo apt-get install wireshark

抓包流程:
sudo wireshark
  1. 选择要抓的网卡---》any
  2. 选择过滤条件并触发:比如:udp.port == 50000
  3. 进行一次网络通信
TCP协议
  • TCP:传输控制协议(流式套接字),传输层
TCP特点
  1. 面向数据流
  2. 面向连接
  3. 安全可靠的传输协议
  4. TCP机制复杂
TCP机制
  • 三次握手:TCP建立连接的时候需经过三次握手,确保通讯双方都已经准备就绪
  • 四次挥手:断开连接,确保通信双方在断开连接前都已经收发数据结束可以由客户端发起,也可以由服务端发起
TCP编程
建立连接connect

int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen)

  • 功能:请求建立连接
  • 参数:
  • sockfd:建立连接的套接字
  • addr:服务端的地址信息
  • addrlen:服务端地址大小
  • 返回值:
  • 成功:0
  • 失败:-1
监听:listen

int listen(int sockfd, int backlog)

  • 功能:监听三次握手
  • 参数:
  • sockfd:监听套接字
  • backlog:允许同时监听的客户端的最大个数
  • 返回值:
  • 成功:0
  • 失败:-1
接收客户端:accept

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen)

  • 功能:接收完成三次握手的客户端
  • 参数:
  • sockfd:监听套接字
  • addr:保存接收到的客户端的地址
  • addrlen:地址信息大小的指针
  • 返回值:
  • 成功:通讯套接字
  • 失败:-1
接收数据recv

ssize_t recv(int sockfd, void *buf, size_t len, int flags)

  • 功能:接收套接字上的数据
  • 参数 :
  • sockfd:套接字
  • buff:存放接收到的数据
  • len:期望读到的字节数
  • flags:标志:0 默认方式
  • 返回值:
  • 成功:实际收到的字节数
  • 失败:-1
  • 对方关闭套接字:0
相关推荐
玖玥拾1 小时前
C/C++ 数据结构(七)栈、容器适配器
c语言·数据结构·c++··容器适配器
何以解忧,唯有..1 小时前
Go语言循环语句详解:for、range与循环控制
开发语言·算法·golang
謓泽1 小时前
C语言不是语法,是通往机器的地图。
c语言·开发语言
云水一下1 小时前
从零开始学 PHP 系列(一):PHP 的前世今生与开发环境搭建
开发语言·php
飞天狗1111 小时前
零基础JavaWeb入门——第五课第二小节:九大内置对象 · 第2个:response(响应对象)
java·开发语言
DJ斯特拉1 小时前
axios快速使用
开发语言·前端·javascript
不会C语言的男孩1 小时前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言
xingpanvip2 小时前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
于先生吖2 小时前
教育类Java实战项目:在线错题整理平台分层架构设计与接口源码解析
java·开发语言