在UDP中的不同套接字中发送和接收

时间:2014-12-29 18:18:04

标签: c++ sockets udp boost-asio

稍后在我的应用程序中,我将有三个线程:一个线程监听端口上的数据,一个线程将数据发送到同一端口上的地址。最后一个在这里并不重要。

目前,我不使用线程,我只是想做一些测试。

我的问题如下:

如果我只是使用服务器发送和接收数据,则没有问题。但是当它是发送数据的客户端时,它就像遥远的同伴没有收到任何东西。

我的服务器代码:

#include "server.h"


using namespace boost::asio::ip;
using Peer = udp::endpoint;

Server::Server(boost::asio::io_service& io_service, Peer peer, Agent& agent) :  
    socket_(io_service, Peer(boost::asio::ip::udp::v6(), peer.port())),
    recv_buffer_(), send_buffer_(), root_(peer), agent_(agent)
{
/* //when this is uncomment, that works fine    
    BOOST_LOG_TRIVIAL(info) << "Server Initialisation:";

    std::shared_ptr<PeersReq> peersreq(new PeersReq());
    std::vector<std::shared_ptr<Tlv>> tlv_vector;
    tlv_vector.push_back(peersreq);
    Packet packet(tlv_vector);

    write_log(packet, peer);

    boost::asio::streambuf request;
    std::ostream os(&request);
    packet.format(os);
    std::cout << peer.address() << std::endl;
    int n = static_cast<int>(socket_.send_to(request.data(),peer));

    BOOST_LOG_TRIVIAL(debug) << "Bytes sent: " << n << std::endl;
*/
}

void Server::write_log(Packet packet, Peer peer) {
    BOOST_LOG_TRIVIAL(info)  << "Packet send to " << peer.address().to_string() << ":" << peer.port() << std::endl;
    BOOST_LOG_TRIVIAL(info)  << "Packet\n" << packet << std::endl;
}

void Server::receive() {
    Peer peer;
    BOOST_LOG_TRIVIAL(info) << "Now listening on port:" << root_.port() << std::endl;
    socket_.receive_from(boost::asio::buffer(recv_buffer_), peer);
    BOOST_LOG_TRIVIAL(info) << "Packet received" << std::endl;
    std::cout << static_cast<int>(recv_buffer_[0]) << std::endl;
    std::cout << static_cast<int>(recv_buffer_[1]) << std::endl;

    if (recv_buffer_[0] != 57) //TO DO magic number
        exit(EXIT_FAILURE); //Change this to send a bad
    else if(recv_buffer_[1] != 0) //TO DO magic number
        exit(EXIT_FAILURE);

    uint16_t packet_length = static_cast<uint16_t>((recv_buffer_[2]<<8)+recv_buffer_[3]);
    std::cout << packet_length << std::endl;
    if (packet_length > 1024) //TODO magic number
        exit(EXIT_FAILURE);
    //maybe log ?
    for(int i = 0 ; i < packet_length ; i++)
        std::cout << i << ":" << (static_cast<int>(recv_buffer_[i+4]) & 0xFF) << std::endl;

    Packet packet = Packet::from_string(recv_buffer_.data()+4, packet_length);
    std::cout << "packet received" << std::endl;
    std::cout << packet << std::endl;
    //agent_.notify(packet, peer);
    /*
    boost::asio::streambuf request;
    std::ostream os(&request);
    packet_to_send.format(os);
    //std::cout << request.size() << std::endl;
    socket_.send_to(request.data(), peer);
    */

    receive();
}

我客户的代码如下:

Client::Client(boost::asio::io_service& io_service, Peer peer) : socket_(io_service, Peer(boost::asio::ip::udp::v6(), peer.port())) , peers_(), queue_peer_() {
    //socket_.open(boost::asio::ip::udp::v6());
    peers_.insert(peer);
    queue_peer_.insert(std::make_pair(peer.address().to_string(),std::vector<std::shared_ptr<Tlv>>()));
    std::shared_ptr<PeersReq> peersReq(new PeersReq());
    add_tlv_to_queue(peersReq, peer);
    send();
}

void Client::add_tlv_to_queue(std::shared_ptr<Tlv> tlv, Peer peer) {

    if(queue_peer_.find(peer.address().to_string())!= queue_peer_.end()) {
        peers_.insert(peer);
        queue_peer_.insert(std::make_pair(peer.address().to_string(),std::vector<std::shared_ptr<Tlv>>()));
    }

    queue_peer_.find(peer.address().to_string())->second.push_back(tlv);
}

void Client::send() {
    for ( std::unordered_map<std::string, std::vector<std::shared_ptr<Tlv>>>::iterator it = queue_peer_.begin(); it != queue_peer_.end(); ++it ) {
        if(it->second.size()>0) {           
            boost::asio::streambuf request;
            std::ostream os(&request);
            Packet packet(it->second);
            packet.format(os);

            Peer peer = get_peer_from_string(it->first);
            std::cout << peer.address() << std::endl;
            int n = static_cast<int>(socket_.send_to(request.data(),peer));
        }
    }
}


Peer Client::get_peer_from_string(std::string string) {
    Peer peer;
    for(std::set<Peer>::const_iterator it =peers_.begin() ; it != peers_.end() ; it++) {        
        if(it->address().to_string() == string) 
            peer=*it;       
    }
    //undefined behaviour if the peer is not registred. But it shouldn't happen
    return peer;
}

主要使用以下代码:

Agent agent(storage, peer);
Server server(io_service_server, peer, agent);
Client client(io_service_client, peer);
server.receive();

我不知道我是不是做了什么坏事,或者有什么特别的东西来获得这个行为。

编辑:

这是一个片段:

#include<array>
#include<boost/asio.hpp>
#include<iostream>

using Peer = boost::asio::ip::udp::endpoint;
using namespace boost::asio::ip;


class Server {
public:
    Server(boost::asio::io_service& io_service, Peer peer);
    void receive();

private:
    boost::asio::ip::udp::socket socket_;
    std::array<char, 1024> recv_buffer_;
};

Server::Server(boost::asio::io_service& io_service, Peer peer) :
    socket_(io_service, Peer(boost::asio::ip::udp::v6(), peer.port())),
    recv_buffer_()
{
    boost::asio::streambuf request;
    std::ostream os(&request);
    os << "Server";

    int n = static_cast<int>(socket_.send_to(request.data(),peer));

}

void Server::receive() {
    Peer peer;
    socket_.receive_from(boost::asio::buffer(recv_buffer_), peer);
    std::cout << static_cast<int>(recv_buffer_[0]) << std::endl;
    receive();
}

class Client {
public:
    Client(boost::asio::io_service& io_service, Peer peer);
    void send(Peer peer);

private:
    boost::asio::ip::udp::socket socket_;
};


Client::Client(boost::asio::io_service& io_service, Peer peer) : socket_(io_service) {
    socket_.open(boost::asio::ip::udp::v6());
    send(peer);
}

void Client::send(Peer peer) {
    boost::asio::streambuf request;
    std::ostream os(&request);
    os << "Client";
    int n = static_cast<int>(socket_.send_to(request.data(),peer));        
}

int main(int argc, char* argv[]) {

    boost::asio::io_service io_service_client;
    boost::asio::io_service io_service_server;
    Peer peer;
    peer.address(); //Add an address here
    peer.port(12345);
    Client client(io_service_client, peer);
    Server server(io_service_server, peer);
    return 0;
}

0 个答案:

没有答案