首页 > 编程语言 >使用 C++ 实现网络编程 NetWork(pro版)

使用 C++ 实现网络编程 NetWork(pro版)

时间:2024-10-22 17:17:42浏览次数:8  
标签:NetWork int pro sock C++ fd type nw

上一次小编分享了C++实现网络编程NetWork,这是链接:

C++ 网络通信类 Network 的实现详解-CSDN博客

这次小编带着改进之后的NetWork归来!

在现代计算机网络中,网络通信是不可或缺的一部分。本文将介绍如何使用C语言实现一个简单的网络通信库,涵盖TCP和UDP协议的基本功能。我们将通过一个示例代码库进行详细讲解,以便更好地理解网络编程的核心概念。

1. 类的定义

class NetWork 
{
    int type;           // 通信协议类型
    int sock_fd;        // socket 描述符
    sockaddr_in addr;   // 通信地址
    int addrlen;        // 通信地址字节数
    bool issvr;         // 是否是服务器
public:
    NetWork(void);
    NetWork(int type, const char* ip, short port, bool issvr = false);
    ~NetWork(void);
    bool open(void);
    NetWork* accept_nw(void);
    int send_nw(const char* buf, int flag = 0);
    int send_nw(const void* buf, size_t len, int flag = 0);
    int recv_nw(void* buf, size_t len, int flag = 0);
};

1.1 成员变量

  • type: 代表使用的通信协议类型(如 TCP、UDP)。
  • sock_fd: 用于标识 socket 的描述符。
  • addr: 存储通信地址的结构体。
  • addrlen: 地址结构的大小。
  • issvr: 布尔值,表示该 socket 是否是一个服务器。

1.2 构造函数与析构函数

  • NetWork(void): 默认构造函数,初始化成员变量。
  • NetWork(int type, const char* ip, short port, bool issvr): 带参数的构造函数,用于初始化网络连接。
  • ~NetWork(void): 析构函数,关闭 socket 并释放资源。

2. 打开连接

2.1 bool open(void)

该方法负责创建 socket 并根据类型执行相应的操作(如绑定、监听或连接)。

bool NetWork::open(void)
{
    //创建socket对象
    sock_fd = socket(AF_INET,type,0);
    if(sock_fd < 0)
    {
        perror("socket");
        return false;
    }
    //根据type和issvr执行以下流程
    if (issvr) 
    {
        // 服务器端绑定和监听
        if (bind(sock_fd, (sockaddr*)&addr, addrlen)) 
        {
            perror("bind");
            return false;
        }     
        if (type == SOCK_STREAM && listen(sock_fd, 50))
        {
           perror("listen");
           return false;
        }
    }
     else if (type == SOCK_STREAM && connect(sock_fd,(sockaddr*)&addr,addrlen)) 
    {
        perror("connect");
        return false;
    }
    return true;
}
  • 使用 socket 函数创建 socket,返回的描述符存储在 sock_fd 中。
  • 根据 issvrtype,服务器会执行绑定和监听操作,而客户端则尝试连接。

3. 处理连接

3.1 NetWork* accept_nw()

这是一个用于接受连接的函数,只有 TCP 服务器可以调用。

NetWork* NetWork::accept_nw() 
{
    if (type != SOCK_STREAM || !issvr) 
    {
        puts("只有type为SOCK_STREAM 且为服务端才能调用该函数\n");
    }

    NetWork* nw = new NetWork;
    nw->sock_fd = accept(sock_fd, (sockaddr*)&nw->addr, &nw->addrlen);

    if (nw->sock_fd < 0) 
    {
        delete nw;
        perror("accept");
        return NULL;
    }

    return nw;
}
  • 调用 accept 方法接受客户端连接,并返回一个新的 NetWork 对象。

4. 数据传输

4.1 发送数据

send_nw 方法有两个重载,支持发送字符串和自定义长度的缓冲区。

int NetWork::send_nw(const char* buf,int flag )
{
    if(type == SOCK_STREAM)
        return ::send(sock_fd,buf,strlen(buf)+1,flag);
    else
        return sendto(sock_fd,buf,strlen(buf)+1,flag,(sockaddr*)&addr,addrlen);
}

int NetWork::send_nw(const void* buf, size_t len,int flag )
{
    if (type == SOCK_DGRAM) 
    {
        return sendto(sock_fd, (char*)buf, len, flag, (sockaddr*)&addr, addrlen);
    } 
    else 
    {
        return send(sock_fd,(char*)buf, len, flag);
    }
}
  • 对于 TCP,使用 send 发送数据。
  • 对于 UDP,使用 sendto 发送数据到指定的地址。

4.2 接收数据

recv_nw 方法用于接收数据,支持 TCP 和 UDP。

int NetWork::recv_nw(void* buf, size_t len,int flag ) 
{
    if (type == SOCK_DGRAM) 
    {
        return recvfrom(sock_fd, (char*)buf, len, flag, (sockaddr*)&addr, &addrlen);
    } 
    else 
    {
        return recv(sock_fd, (char*)buf, len, flag);
    }
}
  • 对于 TCP,使用 recv 接收数据。
  • 对于 UDP,使用 recvfrom 从特定地址接收数据。

5. 关键知识点总结

  • Socket 编程: 是实现网络通信的基础,Socket 提供了一个接口,用于在网络上发送和接收数据。
  • TCP vs UDP: TCP 是面向连接的协议,适用于需要可靠传输的场景;UDP 是无连接的,适合实时性要求高但可以容忍数据丢失的场景。
  • 地址结构: sockaddr_in 是用于存储 IPv4 地址的结构,包含了协议族、端口和 IP 地址。

结语

本文通过分析 NetWork 类的实现,展示了 C++ 中如何进行基础的网络编程。通过封装 socket 的常用操作,开发者可以更方便地进行网络通信。希望本篇文章能帮助读者更好地理解网络编程的基础知识和实践应用。

标签:NetWork,int,pro,sock,C++,fd,type,nw
From: https://blog.csdn.net/qq_50394172/article/details/143163695

相关文章

  • 【PR】Adobe Premiere Pro软件下载及安装步骤
    目录一、AdobePremierePro软件简介1.1软件背景1.2主要功能二、系统要求2.1Windows系统要求2.2macOS系统要求2.3网络与其他要求三、安装步骤3.1下载安装包3.2运行安装程序3.3完成安装一、AdobePremierePro软件简介1.1软件背景AdobePremierePro(简......
  • Prompts Royale: 革新提示工程的创新平台
    PromptsRoyale:提示工程的革命性工具在人工智能和自然语言处理领域,提示工程(PromptEngineering)已经成为一项至关重要的技能。然而,创建高质量、高效率的提示往往是一个耗时且具有挑战性的过程。为了解决这个问题,一个名为PromptsRoyale的创新平台应运而生,它旨在彻底改变提......
  • 一文读懂什么是数据即产品(Data as a Product,DaaP)
    企业每天都要产生并消费大量数据,但如果这些数据一直保持在原始格式,就很难真正应用起来。因此,为了充分发挥数据的最大潜力,必须改变组织内部处理数据的方式。“数据即产品”(DaaP)就是这样一种思维方式转变的代表,即将原始数据转化为高质量的信息产品。这种转变不仅会改变企业的数据战......
  • 【代码】约瑟夫问题——c++解决代码
    哈喽大家好!我是@学霸小羊,上次讲了讲约瑟夫问题的背景,今天来讲讲怎样用代码实现。(还没了解背景小伙伴的可以先去下面的网址学习一下)【代码】约瑟夫问题——故事背景https://blog.csdn.net/yangyanbin_sam/article/details/143152232?spm=1001.2014.3001.5501首先,我们要将这个......
  • Pyrene-PEG3-Propargyl|cas:2752164-04-6|Propargyl PEG3 Pyrene|芘甲酰胺-三聚乙二醇-
    Pyrene-PEG3-Propargyl,中文名称为芘甲酰胺-三聚乙二醇-丙炔,以下是对其的详细介绍:一、基本信息英文名称:Pyrene-PEG3-Propargyl别名:PropargylPEG3PyreneCAS号:2752164-04-6分子式:C26H25NO4分子量:415.49纯度:通常95%,适用于科研实验外观:淡黄色或白色固体,具体形态可能因PEG分子量......
  • 域渗透之 内网穿透 隧道技术聊聊看 环境搭建 regeorg技术 proxifier联合使用 一步步让
    Http通道ReGeorg环境搭建win10安装reGeorgwin2003phpstudywin7安装phpstudy软件下载地址通过网盘分享的文件:隧道工具链接:https://pan.baidu.com/s/1Jmh2QbfmIPRdeTuWN9-Dkg?pwd=k81v提取码:k81v试验步骤在win2003和win10之间建立一个隧道那么就将regeorg......
  • Java 的开发效率究竟比 C++ 高在哪里_1
    在比较Java与C++在开发效率上的不同时,我们可以直接指出几点关键差异:Java的自动内存管理、跨平台能力、更强的标准库、以及较好的异常处理机制。特别地,Java的自动内存管理使用垃圾收集器来自动化对象的生命周期管理,这就意味着开发人员不需要手动分配和释放内存,大大减少了内存泄漏......
  • k8s 部署 prometheus
    创建namespaceprometheus-namespace.yamlapiVersion:v1kind:Namespacemetadata:name:ns-prometheus拉取镜像dockerpullswr.cn-north-4.myhuaweicloud.com/ddn-k8s/quay.io/prometheus/prometheus:v2.54.0prometheus配置文件configmapprometheus-configmap.yaml......
  • 【LeetCode】动态规划—790. 多米诺和托米诺平铺(附完整Python/C++代码)
    动态规划—790.多米诺和托米诺平铺题目描述前言基本思路1.定义2.理解问题和递推关系3.解决方法4.进一步优化5.小总结代码实现Python代码Python代码解释总结C++代码C++代码解释总结总结题目描述前言本文将详细讨论LeetCode上的"多米诺和三米诺平铺"问题。......
  • C++文字识别接口介绍-翔云-通用文字识别API接口
    文字识别接口是一种提供给开发者使用的API服务,主要功能是通过光学字符识别(OCR,OpticalCharacterRecognition)技术将图片中的文字转换为可编辑的文本。这种技术广泛应用于各种场景,比如证件识别、票据识别、书籍扫描等。使用第三方平台如翔云文字识别接口通常需要以下几......