未分类

boost库实现UDP通信

本博客将会介绍如何通过boost库实现局域网内两台主机之间的通信。(跨公网通信的客户端部分修改而来,跨公网通信需要添加一个服务端,但是客户端部分基本一样)。

具体实现方法赫写套接字大致相同,就是创建端点,实现多线程,这里主线程发消息,子线程收消息。

首先创建一个

io_service

服务,建立端点并开启套接字。


using namespace boost::asio;

io_service io;
ip::udp::endpoint send_up;
ip::udp::socket sock(io,ip::udp::endpont(ip::udp::v4(),6699)); //默认绑定的端口是6699,这儿就已经创建了,待会就不需要再sock.open()了

 

进行通信的类


class communication{
    public:
        void startWork();
        void doWork();
        void workLoop();//这儿的workLoop函数是用来实现循环接受消息的。
    private:
        std::unique_ptr<std::thread> m_work;
}

void communication::startWork(){
    m_work.reset(new thread([&](){workLoop();}))
}

void communication::workLoop(){
    while(true){
        this::thread::sleep_for(std::chrono::milliseconds(100));//反复刷新,同时防阻塞。
        doWork();
    }
}

void communication::doWork(){
    char recv_buff[1024] = {0};
    sock.receive_from(buffer(recv_buff,1024),send_up);//接收消息,并将消息输出。
    cout<<recv_buff<<endl;
    memset(recv_buff,'\0',1024);
}

上面就是接收端的实现,就是每隔100毫秒就接收一次消息,然后将消息打印出来。

下面这个类是用来拼接ip端口地址这些的,可以不要,在主函数里面实现一步步输入。


class remoteEndpoint{
    public :
    remoteEndpoint(vector<char> in){
        string rep = bufferToStr(in);
        int idx = rep.find(":");
        this->rmIp = rep.substr(0,idx);
        string tmp = rep.substr(idx+1,rep.length()-1);
        this->rmPort = boost::lexical_cast<int>(tmp);
    }
   
    remoteEndpoint(string rep){
        int idx = rep.find(":");
        this->rmIp = rep.substr(0,idx);
        string tmp=rep.substr(idx+1, rep.length()-1);
        this->rmPort=boost::lexical_cast<int>(tmp);
    }
   
    ~remoteEndpoint(){}
   
    string bufferToStr(vector<char> in) {
        string str;
        for(int i=0; i<in.size(); i++) {
            if(in[i]!=0) str+=in[i];
        }
        return str;
    }
   
    string rmEndpoint;
    string rmIp;
    int rmPort;
}

在主函数里面完成端点的建立以及发送消息


int main(){
    communication m_listener;
    string tmp;
   
    cout<<"Please inpput another node's ip:port\n";
   
    cin>>tmp;
   
    remoteEndpoint iServerEp = remoteEndpoint(tmp);
    send_up = ip::udp::endpoint(ip::address::from_string(iServerEp.rmIp),iServerEp.rmPort);
    iServerEp.~remoteEndpoint();
   
    m_listener.startWorking();
   
    while(true){
        string input;
       
        cin>>input;
       
        sock.send_to(buffer(input),send_up);
       
        input.clear();
    }
}

 

下面是完整的代码


#include <boost/lexical_cast.hpp>
#include <boost/asio.hpp>

#include <iostream>
#include <stdlib.h>
#include <thread>
#include <chrono>
#include <unistd.h>

using namespace boost::asio;
using namespace std;

io_service io;
ip::udp::endpoint send_up;
ip::udp::socket sock(io,ip::udp::endpont(ip::udp::v4(),6699)); //默认绑定的端口是6699,这儿就已经创建了,待会就不需要再sock.open()了

class communication{
    public:
        void startWork();
        void doWork();
        void workLoop();//这儿的workLoop函数是用来实现循环接受消息的。
    private:
        std::unique_ptr<std::thread> m_work;
}

void communication::startWork(){
    m_work.reset(new thread([&](){workLoop();}))
}

void communication::workLoop(){
    while(true){
        this::thread::sleep_for(std::chrono::milliseconds(100));//反复刷新,同时防阻塞。
        doWork();
    }
}

void communication::doWork(){
    char recv_buff[1024] = {0};
    sock.receive_from(buffer(recv_buff,1024),send_up);//接收消息,并将消息输出。
    cout<<recv_buff<<endl;
    memset(recv_buff,'\0',1024);
}

class remoteEndpoint{
    public :
    remoteEndpoint(vector<char> in){
        string rep = bufferToStr(in);
        int idx = rep.find(":");
        this->rmIp = rep.substr(0,idx);
        string tmp = rep.substr(idx+1,rep.length()-1);
        this->rmPort = boost::lexical_cast<int>(tmp);
    }
   
    remoteEndpoint(string rep){
        int idx = rep.find(":");
        this->rmIp = rep.substr(0,idx);
        string tmp=rep.substr(idx+1, rep.length()-1);
        this->rmPort=boost::lexical_cast<int>(tmp);
    }
   
    ~remoteEndpoint(){}
   
    string bufferToStr(vector<char> in) {
        string str;
        for(int i=0; i<in.size(); i++) {
            if(in[i]!=0) str+=in[i];
        }
        return str;
    }
   
    string rmEndpoint;
    string rmIp;
    int rmPort;
}

int main(){
    communication m_listener;
    string tmp;
   
    cout<<"Please inpput another node's ip:port\n";
   
    cin>>tmp;
   
    remoteEndpoint iServerEp = remoteEndpoint(tmp);
    send_up = ip::udp::endpoint(ip::address::from_string(iServerEp.rmIp),iServerEp.rmPort);
    iServerEp.~remoteEndpoint();
   
    m_listener.startWorking();
   
    while(true){
        string input;
       
        cin>>input;
       
        sock.send_to(buffer(input),send_up);
       
        input.clear();
    }
}

 

Leave a Reply

邮箱地址不会被公开。 必填项已用*标注