消息队列
-
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 分类:
- 任何TCP/IP实现所提供的服务都用1-1023之间的端口号。 http : 80、8080 FTP: 20/21 TFPT: 69 HTTPS: 443 MQTT :1883
- 端口号从1024-49151是被注册的端口号,被IANA指定为特殊服务使用
- 从49152-65535是动态或私有端口号
网络协议栈

网络配置
- ifconfig :查看Linux下主机的IP地址相关信息
- ping IP地址/域名 :检查当前主机和目标主机是否网络联通
配置过程
- 虚拟机-->>设置-->>网络适配器--->>桥接模式
- 编辑-->>虚拟网络编辑器-->>更改设置-->>VMnet0设置为桥接模式-->>桥接到Windows正在上网的网卡-->>应用---->>确定
- 修改配置文件 sudo vim /etc/network/interfaces
- 重启网络服务 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
- 选择要抓的网卡---》any
- 选择过滤条件并触发:比如:udp.port == 50000
- 进行一次网络通信
TCP协议
- TCP:传输控制协议(流式套接字),传输层
TCP特点
- 面向数据流
- 面向连接
- 安全可靠的传输协议
- 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