LINUX网络编程:Tcpsocket封装

embedded/2024/9/22 19:58:05/

目录

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;
}


http://www.ppmy.cn/embedded/105002.html

相关文章

ubuntu设置为自己需要的屏幕分辨率

先说一下我处理该问题的大体背景&#xff1a;我是学习Linux的新手&#xff0c;刚学完嵌入式Linux驱动开发相关课程。现在想接着学习一下QT开发。我是在电脑上装了虚拟机之后安装的ubuntu系统。因为换了电脑&#xff0c;所以重新装了ubuntu系统。但是&#xff0c;装完ubuntu系统…

OmniGraffle Pro for Mac 思维导图软件安装

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功 三、运行测试安装完成&#xff01;&#xff01;&#xff01; 效果 一、下载软件 下载软件…

ElasticSearch-基础操作

基本概念索引操作 创建索引修改索引配置查询索引删除索引 文档操作 添加&#xff08;索引&#xff09;文档&#xff1a;POST和PUT修改文档 全量更新增量修改 使用_update部分更新使用_update_by_query 更新文档 并发场景下修改文档 查询文档 根据id查询文档条件查询 _search RE…

WPF在ListBox内嵌入panel然后数据绑定中加入CheckBox

界面操作为&#xff1a; <ListBox Name"ListBoxMain" Grid.ColumnSpan"2" Grid.Row"1" Grid.Column"1" ><ListBox.ItemsPanel><ItemsPanelTemplate><WrapPanel HorizontalAlignment"Left" /> <!…

8.29 C++

作业 #ifndef CLASS_H #define CLASS_H #include <iostream> using namespace std; class Rect { private:int width;int height; public:void init(int w,int h);void set_w(int w);void set_h(int h);void show(); }; #endif // CLASS_H#include "class.h"v…

C++枚举类(强类型枚举、强枚举)(枚举类与switch语句)

文章目录 C枚举类及其应用深入解析引言枚举类的基本使用传统枚举的限制- 类型安全不足- 作用域污染 枚举类的优势- 强类型- 作用域限定- 指定底层类型 声明和使用枚举类- 基本语法- 示例代码 枚举类的高级应用- 明确指定枚举值- 底层类型的指定- 枚举类与switch语句 枚举类在现…

20-22 - 打造专业的编译环境

---- 整理自狄泰软件唐佐林老师课程 文章目录 1. 大型项目的编译&#xff08;无第三方库&#xff09;1.1 大型项目的目录结构&#xff08;无第三方库&#xff09;1.2 项目结构设计分析1.3 需要打造的编译环境1.4 解决方案设计 2. 第 1 阶段任务2.1 关键的实现要点2.2 模块 make…

Maven <parent> 标签的作用及使用详解

在使用 Maven 进行项目构建时&#xff0c;<parent> 标签是一个非常重要的配置元素。它允许子模块继承父模块的配置&#xff0c;从而实现一致性和配置管理的简化。本文将详细介绍 <parent> 标签的主要作用&#xff0c;并通过示例来说明其使用方式和关键点。 <pa…