文章目录:
1.协议
2.锁
3.网络层次模型
4.以太网帧和ARP协议
5.IP协议
6.UDP协议
7.TCP协议
8.BS模式和CS模式
9.网络套接字(socket)
10.网络字节序
11.IP地址转换函数
12.sockaddr地址结构
学习Linux的网络编程原则上基于:Linux的系统编程 和 Linux基础的Shell编程(第十章);除此之外还包含了计算机网络的知识
Linux基础shell编程——>Linux 系统编程——>Linux 网络编程
1.协议
互联网协议(Internet Protocol Suite)
什么是协议:从应用的角度出发,协议可理解为“规则”,是数据传输和数据的解释的规则 典型协议 传输层 常见协议有TCP/UDP协议 应用层 常见的协议有HTTP协议,FTP协议 网络层 常见协议有IP协议、ICMP协议、IGMP协议 网络接口层 常见协议有ARP协议、RARP协议
TCP传输控制协议(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议 UDP用户数据报协议(User Datagram Protocol)是OSI参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务 HTTP超文本传输协议(Hyper Text Transfer Protocol)是互联网上应用最为广泛的一种网络协议 FTP文件传输协议(File Transfer Protocol) IP协议是因特网互联协议(Internet Protocol) ICMP协议是Internet控制报文协议(Internet Control Message Protocol)它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息 IGMP协议是 Internet 组管理协议(Internet Group Management Protocol),是因特网协议家族中的一个组播协议。该协议运行在主机和组播路由器之间 ARP协议是正向地址解析协议(Address Resolution Protocol),通过已知的IP,寻找对应主机的MAC地址 RARP是反向地址转换协议,通过MAC地址确定IP地址
2.锁
如何避免死锁: 保证资源的获取顺序,要求每个线程获取资源的顺序一致 当得不到已有的资源时,放弃已经获取的资源,等待 读写锁:当读次数远大于写次数时 写独占,读共享 写锁优先级高 锁只有一把 条件变量指明了共享数据区值不值得访问(有无空位或产品),锁是访问共享数据区的通行证 信号量可以看作进化版互斥锁:1-->N,保证同步的同时,提高了并发 sem_wait:给信号量加锁,sem–,lock sem_post:给信号量解锁,sem++,unlock,同时唤醒阻塞在该信号上的线程
3.网络层次模型
物理层:主要定义物理设备标准,如网线的接口类型、光纤的接口类型、各种传输介质的传输速率等 它的主要作用是传输比特流(就是由1、0转化为电流强弱来进行传输,到达目的地后再转化为1、0,也就是我们常说的数模转换与模数转换) 这一层的数据叫做比特 数据链路层:定义了如何让格式化数据以帧为单位进行传输,以及如何让控制对物理介质的访问 这一层通常还提供错误检测和纠正,以确保数据的可靠传输 如:串口通信中使用到的115200、8、N、1 网络层:在位于不同地理位置的网络中的两个主机系统之间提供连接和路径选择 Internet的发展使得从世界各站点访问信息的用户数大大增加,而网络层正是管理这种连接的层 传输层:定义了一些传输数据的协议和端口号(WWW端口80等) 如:TCP(传输控制协议,传输效率低,可靠性强,用于传输可靠性要求高,数据量大的数据) UDP(用户数据报协议,与TCP特性恰恰相反,用于传输可靠性要求不高,数据量小的数据,如QQ聊天数据就是通过这种方式传输的) 主要是将从下层接收的数据进行分段和传输,到达目的地址后再进行重组。常常把这一层数据叫做段 会话层:通过传输层(端口号:传输端口与接收端口)建立数据传输的通路 主要在你的系统之间发起会话或者接受会话请求(设备之间需要互相认识可以是IP也可以是MAC或者是主机名) 表示层:可确保一个系统的应用层所发送的信息可以被另一个系统的应用层读取 例如,PC程序与另一台计算机进行通信,其中一台计算机使用扩展二一十进制交换码(EBCDIC) 而另一台则使用美国信息交换标准码(ASCII)来表示相同的字符 如有必要,表示层会通过使用一种通格式来实现多种数据格式之间的转换 应用层:是最靠近用户的OSI层。这一层为用户的应用程序(例如电子邮件、文件传输和终端仿真)提供网络服务
OSI七层模型结构(我的记忆方法_巫术网传会报应): 物、数、网、传、会、表、应 TCP/IP 4层模型结构:网(链路层/网络接口层)、网、传、应 应用层:http、ftp、nfs、ssh、telnet。。。 传输层:TCP、UDP 网络层:IP、ICMP、IGMP 链路层:以太网帧协议、ARP
网络传输数据封装流程
数据没有封装之前,是不能在网络中传递。 数据-》应用层-》传输层-》网络层-》链路层 --- 网络环境 只有应用层协议在用户态可见,往下的都处在内核中(什么是内核?)
4.以太网帧和ARP协议
以太网帧协议:根据mac地址,完成数据包传输 以太网帧中的目的地址和源地址是指MAC地址 ARP协议(数据报格式):根据 Ip 地址获取 mac 地址
5.IP协议
版本: IPv4、IPv6 -- 4位 TTL: time to live 。 设置数据包在路由节点中的跳转上限。每经过一个路由节点,该值-1, 减为0的路由,有义务将该数据包丢弃 源IP: 32位。--- 4字节 192.168.1.108 --- 点分十进制 IP地址(string) --- 二进制 目的IP:32位。--- 4字节
6.UDP协议
源端口号 目的端口号 序号 确认序号 数据偏移 保留 URG/ACK/PSH/RST/SYN/FIN 窗口 检验和 紧急指针 选项和填充(从这开始往上是首部) 数据
IP地址:可以在网络环境中,唯一标识一台主机 端口号:可以网络的一台主机上,唯一标识一个进程 多数应用程序使用5000以下的端口(80端口:http协议) ip地址+端口号:可以在网络环境中,唯一标识一个进程
7.TCP协议
16位:源端口号 16位:目的端口号 32序号 32确认序号 4位首部长度 保留6位 URG/ACK/PSH/RST/SYN/FIN 16位窗口大小 16位检验和 16位紧急指针 选项(从这开始往上是报头) 数据
8.BS模式和CS模式
C/S:Client/Server B/S:Browser/Server 优点: 缓存大量数据、协议选择灵活、速度快 安全性、跨平台、开发工作量较小 缺点: 安全性差、开发工作量大、跨平台难 不能缓存大量数据、必须严格遵守http协议
9.网络套接字(socket)
一个文件描述符指向一个套接字(该套接字内部由内核借助两个缓冲区实现) 在通信过程中, 套接字一定是成对出现的
10.网络字节序
小端法:(pc本地存储) 高位存高地址。地位存低地址。 int a = 0x12345678 大端法:(网络存储) 高位存低地址。地位存高地址。 htonl --> 本地--》 网络 (IP) 192.168.1.11 --> string --> atoi --> int --> htonl --> 网络字节序 htons --> 本地--》 网络 (port) ntohl --> 网络--》 本地(IP) ntohs --> 网络--》 本地(Port)
用库函数做网络字节序和主机字节序的转换
#include<arpa/inet.h> uint32_t htonl(uint32_t hostlong); //主要针对IP uint16_t htons(uint16_t hostshort); //主要针对port uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);
11.IP地址转换函数
由于如
192.168.45.2
这种的IP地址为点分十进制表示,需要转化为uint32_t
型,有现成的函数(IPv4和IPv6都可以转换)int inet_pton(int af, const char *src, void *dst); 本地字节序(string IP) ---> 网络字节序 af:AF_INET、AF_INET6 src:传入,IP地址(点分十进制) dst:传出,转换后的 网络字节序的 IP地址。 返回值: 成功: 1 异常: 0, 说明src指向的不是一个有效的ip地址。 失败:-1 const char *inet_ntop(int af, const void *src, char *dst, socklen_t size); 网络字节序 ---> 本地字节序(string IP) af:AF_INET、AF_INET6 src: 网络字节序IP地址 dst:本地字节序(string IP) size: dst 的大小。 返回值: 成功:dst、失败:NULL
12.sockaddr地址结构
IP + port --> 在网络环境中唯一标识一个进程
struct sockaddr_in addr; addr.sin_family = AF_INET/AF_INET6 man 7 ip addr.sin_port = htons(9527); int dst; inet_pton(AF_INET, "192.157.22.45", (void *)&dst); addr.sin_addr.s_addr = dst; 【*】addr.sin_addr.s_addr = htonl(INADDR_ANY); 取出系统中有效的任意IP地址。二进制类型。 bind(fd, (struct sockaddr *)&addr, size);
举例
/*相初始化*/ addr.sin_family=AF_INET/AF_INET6; addr.sin_port=htons(9527); //端口号为short类型(16bit) int dst; inet_pton(AF_INET,"192.168.10.2",(void*)&dst); addr.sin_addr.s_addr=dst; /*或者采取下面的方法*/ addr.sin_addr.s_addr=htonl(INADDR_ANY) //取出系统中任意有效的IP地址 /*相关结构体定义,在man 7 ip*/ struct sockaddr_in{ sa_family_t sin_family; in_port_t sin_port; struct in_addr sin_addr; }; struct in_addr{ uint32_t s_addr; }; struct sockaddr_in addr; int bind(int sockfd,const struct sockaddr* addr,socklen_t addrlen); /*struct sockaddr是早已废弃的数据结构,已不再使用,用新的时注意强转一下*/ int ret = bind(sockfd,(struct sockaddr*)&addr,size);