C++——NetWork

news2024/10/24 7:13:51

1.network.h

#include <iostream>
#include <winsock2.h>
#include <cstring>

class NetWork 
{
    int type;           // 通信协议类型
    int sock_fd;        // socket 描述符
    sockaddr_in addr; // 通信地址
    int addrlen;  // 通信地址字节数
    bool issvr;         // 是否是服务器
        // 关闭 socket 套接字并释放内存
public:
    NetWork(void);
    NetWork(int type,  const char* ip, short port, bool issvr=false);
    ~NetWork(void);
    bool open(void);

    // 等待连接,只有TCP协议的服务器才能调用
    NetWork* accept_nw(void);

    // 具备 send 和 sendto 的功能
    int send_nw(const char*buf,int flag = 0);
    int send_nw(const void* buf, size_t len,int flag = 0);

    // 具备 recv 和 recvfrom 的功能
    int recv_nw(void* buf, size_t len,int flag = 0);

    
};

 2.network.cpp

#include "network.h"
#include <iostream>
#include <stdexcept>

NetWork::NetWork(void)
{
    addrlen = sizeof(addr);
    type = SOCK_STREAM;
    issvr = false;
}

NetWork::NetWork(int type, const char* ip,short port, bool issvr):type(type),issvr(issvr)
{   
    //不在构造函数中创建socket,因为socket创建可能失败,而构造函数是没有返回值的,不能在此创建
    
    // 初始化地址结构体
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip);
    addrlen = sizeof(addr);
}

NetWork::~NetWork(void) 
{
    closesocket(sock_fd);
}

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

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

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

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

NetWork已经封装好了下面来使用

server.cpp

#include "network.h"
#include <Windows.h>
#include <pthread.h>
#include <cstdlib>
#include <cstring>
 using namespace std;

#define buf_size (4096)
void* server(void* arg)
{
    NetWork* cnw = static_cast<NetWork*>(arg);
    char* buf = new char[buf_size];
    for (;;)
    {
        //接收请求
        int ret = cnw->recv_nw(buf, buf_size);
        if (ret <= 0 || 0 == strcmp("quit", buf))
        {
            printf("客户端%d退出\n", cnw);
            delete cnw;
            delete buf;
            return NULL;
        }
        printf(" recv:%s bits:%d\n",  buf, ret);
        //响应请求
        strcat(buf, "::return");
        ret = cnw->send_nw(buf);
        if (ret <= 0)
        {
            printf("客户端退出\n");
            delete cnw;
            delete buf;
            return NULL;
        }
    }
    //关闭

    pthread_exit(NULL);
    
}

int main(int argc,const char * argv[])
{
    if(argc!=3)
    {
        printf("参数格式输入错误:./server + ip + port\n");
        return 0;
    }
    
    NetWork * snw = new NetWork(SOCK_STREAM,argv[1],atoi(argv[2]),true);
    if(!snw->open())
    {
       delete snw;
       return -1;
    }
    for(;;)
    {
        NetWork * cnw = snw->accept_nw();
        if(cnw ==NULL)
        {
            continue;
        }
        pthread_t tid;
        pthread_create(&tid, NULL, server, (void*)cnw);
      
        // 分离线程,让线程结束后自动回收资源
        pthread_detach(tid);
    }

}

client.cpp:不要需要开多线程,服务器开多线程因为,服务器要处理多用户发来的请求

#include "network.h"
#include <Windows.h>
#include <pthread.h>
#include <cstdlib>
#include <cstring>
 using namespace std;

#define buf_size (4096)

int main(int argc,const char * argv[])
{
    if(argc!=3)
    {
        printf("参数格式输入错误:./server + ip + port\n");
        return 0;
    }

    NetWork * cnw = new NetWork(SOCK_STREAM,argv[1],atoi(argv[2]));
    if(!cnw->open())
    {
       delete cnw;
       return -1;
    }
   
    char* buf = new char[buf_size];
    for (;;)
    {
        cout<< "<<<"<<endl;
        cin.getline(buf, buf_size);
        //发送请求
       int   ret = cnw->send_nw(buf);
        if (ret <= 0)
        {
            printf("客户端退出\n");
            delete cnw;
            delete buf;
            return 0;
        }
        //接收请求
         ret = cnw->recv_nw(buf, buf_size);
        if (ret <= 0 || 0 == strcmp("quit", buf))
        {
            printf("客户端%d退出\n", cnw);
            delete cnw;
            delete buf;
            return 0;
        }
        printf(" recv:%s bits:%d\n",  buf, ret);
     
    }
    //关闭
      
    
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2222202.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ESP32 S3 语音识别 语音唤醒程序流程

ESP32 S3 语音识别 语音唤醒程序流程 参考例程首先进行esp_periph_set_init 初始化之后执行setup_player&#xff0c;之后执行start_recorder&#xff0c;识别的主处理voice_read_task 参考例程 D:\Espressif\esp-adf\examples\speech_recognition\wwe\ 首先进行esp_periph_se…

零知识学习WLAN漫游二、无线漫游介绍(2)

接前一篇文章&#xff1a;零知识学习WLAN漫游一、无线漫游介绍&#xff08;1&#xff09; 本文内容参考&#xff1a; WLAN漫游简介_漫游主动性-CSDN博客 无线漫游_百度百科 无线漫游简述-CSDN博客 特此致谢&#xff01; 一、WLAN漫游简介 3. 漫游协议和快速漫游协议 802.…

算法的学习笔记—数字在排序数组中出现的次数(牛客JZ53)

&#x1f600;前言 在编程中&#xff0c;查找有序数组中特定元素的出现次数是一个常见的问题。本文将详细讲解这个问题的解决方案&#xff0c;并通过二分查找法优化效率。 &#x1f3e0;个人主页&#xff1a;尘觉主页 文章目录 &#x1f970;数字在排序数组中出现的次数&#x…

九、pico+Unity交互开发——触碰抓取

一、VR交互的类型 Hover&#xff08;悬停&#xff09; 定义&#xff1a;发起交互的对象停留在可交互对象的交互区域。例如&#xff0c;当手触摸到物品表面&#xff08;可交互区域&#xff09;时&#xff0c;视为触发了Hover。 Grab&#xff08;抓取&#xff09; 概念&#xff…

深入浅出:深度学习模型部署全流程详解

博主简介&#xff1a;努力学习的22级计算机科学与技术本科生一枚&#x1f338;博主主页&#xff1a; Yaoyao2024往期回顾&#xff1a; 【论文精读】PSAD&#xff1a;小样本部件分割揭示工业异常检测的合成逻辑每日一言&#x1f33c;: 生活要有所期待&#xff0c; 否则就如同罩在…

【国潮来袭】华为原生鸿蒙 HarmonyOS NEXT(5.0)正式发布:鸿蒙诞生以来最大升级,碰一碰、小艺圈选重磅上线

在昨日晚间的原生鸿蒙之夜暨华为全场景新品发布会上&#xff0c;华为原生鸿蒙 HarmonyOS NEXT&#xff08;5.0&#xff09;正式发布。 华为官方透露&#xff0c;截至目前&#xff0c;鸿蒙操作系统在中国市场份额占据 Top2 的领先地位&#xff0c;拥有超过 1.1 亿 的代码行和 6…

想让前后端交互更轻松?alovajs了解一下?

作为一个前端开发者&#xff0c;我最近发现了一个超赞的请求库 alovajs&#xff0c;它真的让我眼前一亮&#xff01;说实话&#xff0c;我感觉自己找到了前端开发的新大陆。大家知道&#xff0c;在前端开发中&#xff0c;处理 Client-Server 交互一直是个老大难的问题&#xff…

查缺补漏----用户工作区,系统缓冲区,外设工作最短时间计算

对于下面这一题&#xff0c;分析起来很简单&#xff1a; 答案&#xff1a;C 以上是单缓冲区&#xff0c;补充双缓冲区是什么情况&#xff1a; 1.假设磁盘块与缓冲区大小相同&#xff0c;每个盘块读入缓冲区的时间为15us&#xff0c;由缓冲区送至用户区的时间是5us&#xff0c…

etl-查询错误log日志和oracle删除数据表空间

查看weblogic日志的目录 建立连接ssh root192.168.30.1xx 密码hygd123 找到下面路径中的文件 cd /home/weblogic/Oracle/Middleware/user_projects/domains/base_domain/bapp-logs 查看log日志 tail -f -n 400 Adminservers.log oracle删除表空间&#xff08;切换到dba用户…

Android 13 SystemUI 隐藏下拉快捷面板部分模块(wifi,bt,nfc等)入口

frameworks/base/packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSFactoryImpl.java createTileInternal(tileSpec)方法注释想隐藏的模块即可。

Qt开发-----线程调度

目录 前言 一、Linux下查看进程的情况 二、线程的创建 三、多线程的创建和使用 前言 以下引用内容源自正点原子Qt开发指南文档。 我们写的一个应用程序&#xff0c;应用程序跑起来后一般情况下只有一个线程&#xff0c;但是可能也有特殊情况。比如我们前面章节写的例程都跑…

《YOLO目标检测》—— YOLOv1 详细介绍

文章目录 一、算法特点二、网络结构三、检测过程四、损失函数五、性能表现六、优缺点 YOLO v1&#xff08;You Only Look Once version 1&#xff09;是一种快速的目标检测算法&#xff0c;以下是对YOLO v1的详细介绍&#xff1a; 一、算法特点 端到端的网络结构&#xff1a;Y…

项目:Boost 搜索引擎

项目&#xff1a;Boost 搜索引擎 1、项目背景 公司&#xff1a;百度、360、搜狗、谷歌 …站内搜索&#xff1a;搜索的数据更垂直&#xff08;相关&#xff09;&#xff0c;数据量小 2、整体框架 3、技术栈和项目环境 技术栈&#xff1a;C/C C11&#xff0c;STL&#xff0c;jso…

【JAVA毕设】基于JAVA的仓库管理系统

一、项目介绍 本系统前端框架采用了比较流行的渐进式JavaScript框架Vue.js。使用Vue-Router实现动态路由&#xff0c;Ajax实现前后端通信&#xff0c;Element-plus组件库使页面快速成型。后端部分&#xff1a;采用SpringBoot作为开发框架&#xff0c;同时集成MyBatis、Redis、…

C#中的LINQ之美:优雅的数据查询与操作

LINQ&#xff08;Language Integrated Query&#xff0c;语言集成查询&#xff09;是C#中一个强大的工具&#xff0c;它将查询功能直接融入到语言中&#xff0c;使开发者能够以一种更直观、更接近自然语言的方式来操作数据。LINQ不仅能极大地提高开发效率&#xff0c;而且让代码…

掌握ElasticSearch(五):查询和过滤器

一、查询和过滤器的区别 在 Elasticsearch 中&#xff0c;查询&#xff08;Query&#xff09;和过滤器&#xff08;Filter&#xff09;是用于检索和筛选数据的重要组成部分。它们虽然都能用来查找文档&#xff0c;但在性能和用法上有所不同。下面详细介绍查询和过滤器的概念以…

Lucas带你手撕机器学习——K近邻

K近邻 (K-Nearest Neighbor KNN) K近邻算法&#xff08;K-Nearest Neighbors, KNN&#xff09;是一种简单直观的机器学习算法&#xff0c;适用于分类和回归问题。它的核心思想是&#xff1a;判断一个数据点的类别或预测值时&#xff0c;参考它在特征空间中最近的 KKK 个数据点…

【2024】【字节青训营】:字节青训营入营测试题——Java版本(已提交通过)

目录 简单题目 计算x到y的最小步数 环状 DNA 序列的最小表示法 Base32 解码和编码 打点计时器 兔群繁殖之谜 完美整数 找出整数数组中占比超过 一半 的数 找出最长的神奇数列 找单独的数 字符串最短循环字串 二进制反码转换问题 中等题目 简单四则运算 数字翻译…

什么是微服务中的反应性扩展?

大家好&#xff0c;我是锋哥。今天分享关于【什么是微服务中的反应性扩展&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 什么是微服务中的反应性扩展&#xff1f; Reactive Extensions 也称为 Rx。这是一种设计方法&#xff0c;我们通过调用多个服务来收集结果…

STM32G474使用TIM2触发DAC输出输出正弦波

STM32G474使用TIM2触发DAC输出&#xff0c;数据从内存到外设就要使用DMA来协助。DAC1每隔1秒输出一个正弦波数据&#xff0c;就会模拟近似得到模拟的正弦波形。用来测试CPU内部的运算放大器&#xff0c;或者用作其它模拟输入信号。 测试程序如下&#xff1a; #include "…