欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 时评 > LINUX网络编程:Tcpsocket封装

LINUX网络编程:Tcpsocket封装

2024/10/25 0:25:31 来源:https://blog.csdn.net/W2155/article/details/141712985  浏览:    关键词:LINUX网络编程:Tcpsocket封装

目录

1.使用Tcp套接字的流程

2.模板方法设计模式

3.socket.hpp

1.搭建抽象类的算法框架

2.具体类算法实现

2.1创建套接字

2.2绑定

2.3套接字设为监听

2.4接收链接

2.5客户端连接服务器


在使用Tcp套接字时,很多的流程都是固定的,将这些固定的流程封装,更方便后续的使用。

1.使用Tcp套接字的流程

1.创建套接字

2.与网络的信息进行绑定,如ip,端口号

3.将套接字的状态设为监听

4.接收客户端链接

5.进行业务处理

将以上流程都使用面向对象的方式封装,只对外提供接口。

2.模板方法设计模式

在父类(抽象类)中定义出各个算法的框架。

通过子类(具体类)继承父类的框架,将虚方法进行重写。

3.socket.hpp

1.搭建抽象类的算法框架

// inet就是这样的一个类存储这网络的信息
//class inetinfo
//{
//    std::string _ip;//ip
//    uint16_t _port;//端口 
//    struct sockaddr_in _addr;
//};class Socket
{
public://纯虚函数 子类继承之后必须重写virtual void createSokcet() = 0;//创建套接字virtual void bindSocket(inetinfo &info) = 0;//绑定套接字virtual void listen() = 0;//设为监听virtual sockptr accepter(inetinfo &info) = 0;//接收链接virtual bool connecter(inetinfo &info) = 0;//客户端连接服务器public:void constructListenSocket(inetinfo &info)//创建服务端的套接字{createSokcet();bindSocket(info);listen();}void construcutClintSocket(inetinfo &info)//创建客户端的套接字{createSokcet();connecter(info);}
};

2.具体类算法实现

2.1创建套接字

void createSokcet() override
{_listenfd = ::socket(AF_INET, SOCK_STREAM, 0);//创建出一个用来监听的fd,不提供服务if (_listenfd < 0){exit(ERROR::SOCKERROR);}
}

2.2绑定

 void bindSocket(inetinfo &info) override
{sockaddr_in addr;//一个结构体类型bzero(&addr, sizeof(addr));//将这个结构体全部置为0addr.sin_addr.s_addr = inet_addr(info.Ip().c_str());//将字符串类型的ip转化为网络格式ipaddr.sin_port = htons(info._port);//将uint16_t类型的端口号 转化为网络格式的端口addr.sin_family = AF_INET;// 协议族 为AF_INET ipv4的网络协议socklen_t len = sizeof(addr);int n = bind(_listenfd, (sockaddr *)&addr, len);//将创建出来的套接字与网络信息绑定if (n < 0){exit(BINDERROT);}
}

2.3套接字设为监听

因为tcp时面向连接的所以必须先获取连接

void listenOrDie() override
{//将套接字的状态设为监听int n = listen(_listenfd, default_num);//从_listenfd中获取连接,第二参数是链接队列的长度if (n < 0){exit(LISTENERROR);}
}

2.4接收链接

accept接口需要返回一个sockfd用来提供服务,还需要返回一个sockaddr_in标识这个链接是来自哪个ip和端口。

using sockptr = unique_ptr<Socket>;
sockptr accepter(inetinfo &info)
{sockaddr_in addr;bzero(&addr, sizeof(addr));socklen_t len = sizeof(addr);int sockfd = accept(_listenfd, (sockaddr *)&addr, &len);if (sockfd < 0){Log(Info, "accept error");return nullptr;}info = addr;return std::make_unique<Socket>(sockfd); // 返回一个基类的指针 上层就可以多态调用
}

2.5客户端连接服务器

connecter返回直接设置bool类型即可,不需要返回sockptr,因为客户端创建出的socket直接可以用来连接和业务的io。

参数info需要与那个ip和端口进行连接。

bool connecter(inetinfo &info)
{sockaddr_in addr;bzero(&addr, sizeof(addr));socklen_t len = sizeof(addr);addr.sin_addr.s_addr = inet_addr(info.Ip().c_str());addr.sin_family = AF_INET;addr.sin_port = htons(info._port);int n = connect(_listenfd, (sockaddr *)&addr, len);if (n < 0){cout << strerror(errno) << endl;return false;}return true;
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com