封装socket接口,方便后续的使用。
Socket模块介绍
Socket模块简单理解就是对socket套接字的封装,当然不是简单的对socket套接字接口的封装,还需要实现一些方法,比如启动非阻塞通信、创建客户端连接、创建服务器连接等。
其意义是程序中对于套接字的各项操作更加简便。
功能
主要实现的是功能是:
创建套接字(socket())
绑定地址信息(bind())
开始监听(listen())
获取新连接(accept())
向服务器发起连接(connect())
发送数据(send())
接收数据(recv())
启动非阻塞通信(发送非阻塞,接收非阻塞,套接字非阻塞)
创建客户端连接
创建服务器连接
关闭套接字
获取套接字
启动地址端口重用。
代码实现将其细节
成员变量
成员变量只需一个就好,即描述符变量。
private:
int _sockfd;/*套接字描述符*/
1.构造方法
在无参构造中,直接将成员变量_sockfd先初始化为-1,以免随机值作乱。而有参构造中,在使用者的视角下,可以传入一个描述符,比如监听描述符进行Socket对象的创建。
Socket()
:_sockfd(-1)
{}
Socket(int sockfd)
:_sockfd(sockfd)
{}
2.创建套接字
调用socket()方法,创建出sock套接字,接着将其赋值给成员变量_sockfd。在创建时,选择TCP协议和ipv4。
bool CreateSockfd()
{
/*协议域、套接字类型 指定特定协议*/
_sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(_sockfd < 0)
{
ERR_LOG("SCOKFD CREATE FALIED!");
return false;
}
/*创建成功*/
return true;
}
3.绑定地址信息
通过调用bind()方法,绑定服务器自身的ip和端口号。
bool Bind(const std::string &ip,uint16_t port)
{
//int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
struct sockaddr_in addr;//先创建sockaddr结构体,用于填充服务器绑定的ip和端口号
addr.sin_family = AF_INET;/*使用IPV4*/
addr.sin_port = htons(port);/*将端口号转换成网络字节序*/
addr.sin_addr.s_addr = inet_addr(ip.c_str());
socklen_t len = sizeof(struct sockaddr_in);/*获取结构体的长度*/
int ret = bind(_sockfd,(struct sockaddr*)&addr,len);
if(ret < 0)
{
ERR_LOG("BIND FAILED!");
return false;
}
return true;
}
绑定地址信息的操作是:需要创建sockaddr_in结构体,用于存储地址、端口号和协议版本。
创建出结构体后,分别填入协议版本,端口号和ip。
端口号需要将其转成网络字节序,是为了确保不同平台之间的数据交换一致性,htons将主机字节序的短整型数转换为网络字节序的短整型数,网络字节序默认为升序。同样的,在填充ip的时候,inet_addr会接收一个点分十进制的ip地址,inet_addr还会将其转化成网络字节序。
在使用bind绑定的时候,因为struct sockaddr是通用结构体,因此在绑定的时候,需要转化成struct sockaddr类型。
sockaddr_in提供了一个明确的、针对 IPv4 地址的结构,程序员可以直接操作 sin_port
和 sin_addr
成员,而不需要关心如何在 sa_data
字段中编码这些信息,因此我们先使用sockaddr_in结构体进行填充,再转化成sockaddr。
4.开始监听
listen方法需要传入最大监听数量,使用宏定义定义了MAX_LISTEN,直接传入即可。
bool Listen(int backlog = MAX_LISTEN)
{
//int listen(int sockfd, int backlog);
int ret = listen(_sockfd,backlog);
if(ret < 0)
{
ERR_LOG("LISTEN FALIED!");
return false;
}
return true;
}
5.获取新连接
int Accept()
{
//int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
int newfd = accept(_s