ACE基本的UDP通信(二)对UDP封装,并测试:连续发送和连续接收 1.0

这里对UDP进行了封装,封装出了一个UDPSender、一个UDPReceiver。

这里为什么要封装呢?

主要是想简明释义,一个类就一个方法,就做一件事,就一个接口,想用就用没有额外的复旦,构造函数强制要求需要的信息。能创建就能试用。

上面就是封装的理由和动机。

介绍:

UDPSender和UDPReceiver被封装在一个DLL中。因为发送和接收都是针对UDP的,而且就这么两个类,一个DLL比较合适,难道一个类也要单独放在一个DLL里面?真是的,小题大做。

双方由于不需要建立连接的过程,所以一个就连续发送,一个连续接收。

由于接收不过来就会丢包,所以发送速度是接收速度的1/2来缓解接收压力

(其中一次测试,发送10001个,接收到了9860个,之所以丢包就是因为sender和receiver每次动作sleep的时间一样短,改成sender sleep(2time),receiver sleep(1time)就不丢数据了。)


test_UDPSender_main.cpp

#ifndef UDP_H
#include "UDP.h"
#endif

#include <string>
using namespace std;

#include "ace/OS.h"
#include "ace/Message_Block.h"
#include "ace/Service_Config.h"
#include "ace/Reactor.h"

int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) 
{
    if (ACE_Service_Config::open(argc,argv,
        ACE_DEFAULT_LOGGER_KEY,1,0,1) < 0)
    {
        ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%p/n"), ACE_TEXT("Service Config open")), -1);
    }


    ACE_Message_Block* mb = new ACE_Message_Block(5000);
    string str("carea");
    for (int i=0;i<1000;++i)
    {
        mb->copy(str.c_str(),str.size());

    }
    int i = 0;

    while (true)
    {
        //这里对象应该在循环外部创建以提高效率,而不用每次都创建临时对象发送,
        //之所以放到这里是看看临时对象在释放会不会正常释放资源,经过测试是可以的
        ACE_INET_Addr remote_addr("localhost:1032");
        UDPSender udp_sender(1048);

        int length = udp_sender.send_udp(mb->rd_ptr(),mb->length(),remote_addr);

        if (length>0)
        {
            ACE_DEBUG((LM_DEBUG,"OK,send[%d] successed\n",
                ++i));
            ACE_OS::sleep(ACE_Time_Value(0,20000));
            if (i>1000)
            {
                break;
            }
        }
        else
        {
            ACE_DEBUG((LM_ERROR,"NO,send failed\n"));
            break;
        }
    }
    

    mb->release();

    ACE_Reactor::instance()->run_reactor_event_loop();

    return 0;
};
发送端发完了全部的包,每个发送对象发送完毕之后在析构的时候close socket



test_UDPReceiver_main.cpp

#ifndef UDP_H
#include "UDP.h"
#endif

#include "ace/OS.h"
#include "ace/Reactor.h"
#include "ace/Service_Config.h"

int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) 
{
    if (ACE_Service_Config::open(argc,argv,
        ACE_DEFAULT_LOGGER_KEY,1,0,1) < 0)
    {
        ACE_ERROR_RETURN((LM_ERROR, ACE_TEXT("%p/n"), ACE_TEXT("Service Config open")), -1);
    }

    char arr[10001]={0};
    UDPReceiver udp_receiver(1032);
    ACE_INET_Addr remote_addr("localhost:1048");
    int i = 0;
    while (true)
    {

        int length = udp_receiver.receive_udp(arr,sizeof(arr),remote_addr);

        if (length>0)
        {
            ACE_DEBUG((LM_DEBUG,"OK,receive th %ds successed\n",
                ++i));
            ACE_OS::sleep(ACE_Time_Value(0,10000));
        }
        else
        {
            ACE_DEBUG((LM_ERROR,"NO,receive failed\n"));
            break;
        }
    }
    
    ACE_Reactor::instance()->run_reactor_event_loop();


    return 0;
};
接收端收到了全部的包


封装DLL所需的文件

头文件SCP_Export.h

#ifndef SCP_EXPORT_H
#define SCP_EXPORT_H

     #ifdef WIN32       //for windows
         #ifdef SCP_EXPORTS           //for windows generate dll,you have to define SCP_EXPORTS in your preprocessor
         #define SCP_Export __declspec(dllexport)       
         #else      
         #define SCP_Export           //for windows as source file
         #endif
     #else             //for Linux
         #ifdef SCP_EXPORTS           //for Linux as source file          
         #define SCP_Export     
         #else 
         #define SCP_Export           //for Linux generate dll
         #endif
     #endif

#endif

头文件UDP.h

#ifndef UDP_H
#define UDP_H

#include "ace/INET_Addr.h"
#include "ace/SOCK_Dgram.h"
#include "ace/Message_Block.h"
#include "ace/Log_Msg.h"
#include "ace/SOCK_Dgram_Bcast.h"

#include <string>
using std::string;

#ifndef SCP_EXPORT_H
#include "SCP_Export.h"
#endif

class SCP_Export UDP 
{
public:
    explicit UDP(u_short local_port);
    ~UDP();
protected:
    ACE_INET_Addr local_port_addr_;
    ACE_SOCK_Dgram peer_;    //本地地址藏匿于此,发送的时候除了知道目的地址,也要携带本地地址的(因为UDP没有连接这一说)
};

class SCP_Export UDPSender : public UDP
{
public:
    UDPSender(u_short port_number);
    int send_udp (const void* message,const int length,const ACE_INET_Addr& remote_addr);
};

class SCP_Export UDPReceiver : public UDP
{
public:
    //在指定端口接收UDP报文
    explicit UDPReceiver(u_short port_number);
    //返回receive_length == -1 表示未接收到,
    //接收内容放到mb中,
    //对方地址在remote_addr
    int receive_udp(char* buffer,const int buffer_length,ACE_INET_Addr& remote_addr);
};

#endif
源文件UDP.cpp

#include "UDP.h"

UDP::UDP(u_short local_port)
    :local_port_addr_(local_port),peer_(local_port_addr_)
{
    ACE_DEBUG((LM_INFO,"UDP(%d)\n",local_port));
}

UDP::~UDP()
{
    ACE_DEBUG((LM_INFO,"~UDP() socket closed.\n"));
    this->peer_.close();
}

UDPSender::UDPSender(u_short port_number)
    :UDP(port_number)
{
}

int UDPSender::send_udp (const void* message,const int length,const ACE_INET_Addr& remote_addr)
{
    int send_bytes = this->peer_.send(message,length,remote_addr);

    if (send_bytes == -1)
    {
        ACE_ERROR((LM_ERROR,
            ACE_TEXT("(%P|%t) UDP send to %s %p\n"),
            remote_addr.get_host_addr(),
            ACE_TEXT ("failed")));
    }
    return send_bytes;
}

UDPReceiver::UDPReceiver(u_short port_number)
    :UDP(port_number)
{
    ACE_DEBUG((LM_INFO,"UDPReceiver(%d)\n",port_number));
}

int UDPReceiver::receive_udp(char* buffer,const int buffer_length,ACE_INET_Addr& remote_addr)
{
    int receive_length = peer_.recv(buffer,buffer_length,remote_addr);    //接收消息,获取远程地址信息
    if (receive_length != -1)
    {
        string str(buffer,buffer_length);
        ACE_DEBUG((LM_DEBUG,"UDPReceiver receive length[%d]\n",
            receive_length));
    }
    else
    {
        ACE_DEBUG((LM_ERROR,"UDPReceiver::receive_udp failed\n"));
    }

    return receive_length;
}










  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
封装并添加自定义语言,需要遵循以下步骤: 1. 安装 vue3-ace-editor ``` npm install vue3-ace-editor ``` 2. 创建一个 Vue 组件,引入 vue3-ace-editor ``` <template> <div> <vue3-ace-editor v-model="code" :options="aceOptions" /> </div> </template> <script> import { defineComponent } from 'vue'; import VueAceEditor from 'vue3-ace-editor'; export default defineComponent({ name: 'Editor', components: { VueAceEditor }, data() { return { code: '', aceOptions: { // 配置项 }, }; }, }); </script> ``` 3. 在 aceOptions 中添加自定义语言 ``` aceOptions: { mode: 'ace/mode/custom', // 自定义语言的 mode 名称 customMode: { // 自定义语言的配置项 }, }, ``` 4. 创建自定义语言的 mode 文件 在项目中创建一个新的 js 文件,例如 `my-language-mode.js`,并添加以下代码: ``` ace.define('ace/mode/custom', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/mode/text', 'ace/mode/custom_highlight_rules'], function ( require, exports, module ) { 'use strict'; var oop = require('../lib/oop'); var TextMode = require('./text').Mode; var CustomHighlightRules = require('./custom_highlight_rules').CustomHighlightRules; var Mode = function () { this.HighlightRules = CustomHighlightRules; }; oop.inherits(Mode, TextMode); (function () { this.$id = 'ace/mode/custom'; }.call(Mode.prototype)); exports.Mode = Mode; }); ``` 5. 创建自定义语言的 highlight rules 文件 在项目中创建一个新的 js 文件,例如 `my-language-highlight-rules.js`,并添加以下代码: ``` ace.define('ace/mode/custom_highlight_rules', ['require', 'exports', 'module', 'ace/lib/oop', 'ace/mode/text_highlight_rules'], function ( require, exports, module ) { 'use strict'; var oop = require('../lib/oop'); var TextHighlightRules = require('./text_highlight_rules').TextHighlightRules; var CustomHighlightRules = function () { this.$rules = { // 高亮规则 }; }; oop.inherits(CustomHighlightRules, TextHighlightRules); exports.CustomHighlightRules = CustomHighlightRules; }); ``` 6. 在 Vue 组件中引入自定义语言的 mode 和 highlight rules 文件 ``` <script> import { defineComponent } from 'vue'; import VueAceEditor from 'vue3-ace-editor'; import 'path/to/my-language-mode'; import 'path/to/my-language-highlight-rules'; export default defineComponent({ name: 'Editor', components: { VueAceEditor }, data() { return { code: '', aceOptions: { mode: 'ace/mode/custom', customMode: { // 配置项 }, }, }; }, }); </script> ``` 7. 配置自定义语言的高亮规则 在 `my-language-highlight-rules.js` 文件中配置自定义语言的高亮规则。具体的规则可以参考 Ace Editor 的官方文档。 8. 配置自定义语言的模式 在 `my-language-mode.js` 文件中配置自定义语言的模式。具体的模式可以参考 Ace Editor 的官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C++程序员Carea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值