我们要封装Socket,首先我们需要了解Socket需要哪些要素:
1) 首先,一个套接字创建后,需要绑定一块网卡的IP,以及连接的对口号,所以我们先封装InetAddr。
在class中,仅有的一个私有成员就是struct sockaddr_in类型的一个对象,我们需要将该对象的几种赋值与创建封装到类中,这样,我们仅需传递相应的IP与port即可获得一个addr。
在这里,我们为了方便获得该addr的IP及port,封装几个将addr转化为IP及port的函数,这样我们仅需调用函数即可。
然后,我们就可以开始封装Socket的一些基本操作了。
在该类的封装中,我们需要将相应的绑定、监听、接收、设置等操作封装好,这样,我们仅需调用该对象的相应函数,即可获得一个处于监听中的套接字。
对于Linux中自带的read和write函数,我们需要进行另外的封装,由于read函数不一定能将缓存区中的数据读完,所以我们需要实现一个能将读满指定字节的函数readn函数,以及相对应的函数,还需要一个读满一行的高效readline函数。
在SocketIO封装中,readline函数是一个较高效的函数,它通过先预览内核中的一大块数据,查看是否有'\n'的存在,若存在,则读取到'\n'为止,否则将该块数据全部读取,然后继续预览。
接下来我们需要封装TcpConnection,我们需要进一步封装,将Socket与SocketIO相结合,同时设置好相应的接口与回调函数,
接下来,我们需要将IO复用模型epoll与TcpConnection封装在EpollPoller中,我们需要将epoll的大部分操作封装好,与我们前面的接口相对应。我们需要将Connection的名单保存起来,当一个连接断开时,及时将该Connection从名单中删除,然后通过调用回调函数,设置相应的执行函数。在epoll_wait中,当事件过多时,我们需要将events的容量扩大,需要注意。
最后,我们可以开始服务器的最后封装,将EpollPoller与Socket结合封装为TcpServer,我们只需将新建的Socket中的套接字fd传递给EpollPoller,再通过客户实现的功能来初始化相应的回调函数即可,这样,我们的Socket基本封装完毕。
相关代码及简单的测试代码,可以到下面查看: