前言
本文旨在学习socket网络编程这一块的内容,epoll是重中之重,后续文章写reactor模型是建立在epoll之上的。
本专栏知识点是通过零声教育的线上课学习,进行梳理总结写下文章,对c/c++linux课程感兴趣的读者,可以点击链接 C/C++后台高级服务器课程介绍 详细查看课程的服务。
socket编程
socket介绍
传统的进程间通信借助内核提供的IPC机制进行, 但是只能限于本机通信, 若要跨机通信, 就必须使用网络通信( 本质上借助内核-内核提供了socket伪文件的机制实现通信----实际上是使用文件描述符), 这就需要用到内核提供给用户的socket API函数库。
使用socket会建立一个socket pair,如下图, 一个文件描述符操作两个缓冲区。
使用socket的API函数编写服务端和客户端程序的步骤
预备知识
网络字节序
网络字节序:大端和小端的概念
大端: 低位地址存放高位数据, 高位地址存放低位数据
小端: 低位地址存放低位数据, 高位地址存放高位数据
大端和小端的使用使用场合:在网络中经常需要考虑大端和小端的是IP和端口。网络传输用的是大端,计算机用的是小端, 所以需要进行大小端的转换
下面4个函数就是进行大小端转换的函数,函数名的h表示主机host, n表示网络network, s表示short, l表示long。
#include <arpa/inet.h> uint32_t htonl(uint32_t hostlong); uint16_t htons(uint16_t hostshort); uint32_t ntohl(uint32_t netlong); uint16_t ntohs(uint16_t netshort);
上述的几个函数, 如果本来不需要转换函数内部就不会做转换。
IP地址转换函数
IP地址转换函数
int inet_pton(int af, const char *src, void *dst);
p->表示点分十进制的字符串形式
to->到
n->表示network网络
函数说明: 将字符串形式的点分十进制IP转换为大端模式的网络IP(整形4字节数)
参数说明:
af: AF_INET
src: 字符串形式的点分十进制的IP地址
dst: 存放转换后的变量的地址
例如inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr.s_addr);
手工也可以计算: 如192.168.232.145, 先将4个正数分别转换为16进制数,
192—>0xC0 168—>0xA8 232—>0xE8 145—>0x91
最后按照大端字节序存放: 0x91E8A8C0, 这个就是4字节的整形值。
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
1
函数说明: 网络IP转换为字符串形式的点分十进制的IP
参数说明:
af: AF_INET
src: 网络的整形的IP地址
dst: 转换后的IP地址,一般为字符串数组
size: dst的长度
返回值:
成功–返回执行dst的指针
失败–返回NULL, 并设置errno
例如: IP地址为010aa8c0, 转换为点分十进制的格式:
01---->1 0a---->10 a8---->168 c0---->192
由于从网络中的IP地址是高端模式, 所以转换为点分十进制后应该为: 192.168.10.1
struct sockaddr
socket编程用到的重要的结构体:struct sockaddr
//struct sockaddr结构说明: struct sockaddr { sa_family_t sa_family; char sa_data[14]; } //struct sockaddr_in结构: 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 */ }; //网络字节序IP--大端模式
通过man 7 ip可以查看相关说明