github链接(更新中)
https://github.com/pourtheworld/mydb
大纲(更新中)
(0)mydb的架构设想
socket回顾
socket地址(以Internet Socket为例):
本地IP地址与端口;
远程IP地址与端口(适用于已经建立的TCP连接);
协议(TCP、UDP)。
流程图:
socket API:
socket() 创建一个新的套接字并分配资源
bind()用于服务端,将套接字与套接字地址(IP+port)绑定
listen()用于服务端,将绑定的TCP置于监听状态
connect()用于客户端,分配一个本地的空闲端口,并与远程地址连接
accpet()用于服务端,接受一个新的连接请求,并创建一个与其绑定的套接字
select()用于等待一个或者多个指定套接字的下一个读写事件
poll()用于测试一个或者多个套接字的读写状态
setsockopt()配置指定套接字的参数
用于mydb的_ossSocket套接字类
类示意图:其中-代表private,#代表protected,+代表public.
接下来会挑几个重要的函数解析。
big endian/little endian
数值0x2211用两个字节存储,高位字节为0x22,低位字节为0x11。
big endian:0x2211
little endian: 0x1122
网络字节序一般为big endian。
(既然big endian符合人类从高位读的习惯,为什么还要有little endian?
这是因为计算电路一般从低位开始读起,运算效率高。)
创建socket:
//socket的创建函数分为了
//创建一个socket
//创建一个用于listen的socket
//创建一个用于connect的socket
//创建一个已经存在的socket
//这里我们以listen socket为例:
_ossSocket::_ossSocket(unsigned int port,int timeout)
{
//初始化信息
_init=false;
_fd=0;
_timeout=timeout;
//清空本机及对方地址
memset(&_sockAddress,0,sizeof(sockaddr_in));
memset(&_peerAddress,0,sizeof(sockaddr_in));
//设置本机和远程的地址长度
_peerAddressLen=sizeof(_peerAddress);
_addressLen=sizeof(_sockAddress);
//本机选择IPV4,接受任意地址
_sockAddress.sin_family=AF_INET;
//htonl 将主机的长整型转换成网络字节顺序
//htons 将主机的整形转换成网络字节顺序
_sockAddress.sin_addr.s_addr=htonl(INADDR_ANY);
_sockAddress.sin_port=htons(port);
}
初始化socket
//需要注意的是我们将创建socket的准备工作放到了前面去做
//具体的socket创建放到了init中
int _ossSocket::initSocket()
{
int rc=EDB_OK;
if(_init) goto done;
memset(&_peerAddress,0,sizeof(sockaddr_in));
_peerAddressLen=sizeof(_peerAddress);
//创建socket SOCK_STREAM为有保障的,SOCK_DGRAM为无保障的
_fd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(-1==_fd)
{