1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374 |
- #include <iostream>
- #include "config.hpp"
- #include "net.hpp"
- NetIO::NetIO(boost::asio::io_context &io_context, const Config &config)
- : conf(config), myconf(config.nodes[config.my_node_num])
- {
- num_nodes = conf.nodes.size();
- nodesockets.resize(num_nodes);
- me = conf.my_node_num;
- // Node number n will accept connections from nodes 0, ..., n-1 and
- // make connections to nodes n+1, ..., num_nodes-1. This is all
- // single threaded, but it doesn't deadlock because node 0 isn't
- // waiting for any incoming connections, so it immediately makes
- // outgoing connections. When it connects to node 1, that node
- // accepts its (only) incoming connection, and then starts making
- // its outgoing connections, etc.
- tcp::resolver resolver(io_context);
- tcp::acceptor acceptor(io_context,
- resolver.resolve(myconf.listenhost, myconf.listenport)->endpoint());
- for(size_t i=0; i<me; ++i) {
- #ifdef VERBOSE_NET
- std::cerr << "Accepting number " << i << "\n";
- #endif
- tcp::socket nodesock = acceptor.accept();
- #ifdef VERBOSE_NET
- std::cerr << "Accepted number " << i << "\n";
- #endif
- // Read 2 bytes from the socket, which will be the
- // connecting node's node number
- unsigned short node_num;
- boost::asio::read(nodesock,
- boost::asio::buffer(&node_num, sizeof(node_num)));
- if (node_num >= num_nodes) {
- std::cerr << "Received bad node number\n";
- } else {
- nodesockets[node_num] = std::move(nodesock);
- #ifdef VERBOSE_NET
- std::cerr << "Received connection from " <<
- config.nodes[node_num].name << "\n";
- #endif
- }
- }
- for(size_t i=me+1; i<num_nodes; ++i) {
- boost::system::error_code err;
- tcp::socket nodesock(io_context);
- while(1) {
- #ifdef VERBOSE_NET
- std::cerr << "Connecting to " << config.nodes[i].name << "...\n";
- #endif
- boost::asio::connect(nodesock,
- resolver.resolve(config.nodes[i].listenhost,
- config.nodes[i].listenport), err);
- if (!err) break;
- std::cerr << "Connection to " << config.nodes[i].name <<
- " refused, will retry.\n";
- sleep(1);
- }
- // Write 2 bytes to the socket to tell the peer node our node
- // number
- unsigned short node_num = (unsigned short)me;
- boost::asio::write(nodesock,
- boost::asio::buffer(&node_num, sizeof(node_num)));
- nodesockets[i] = std::move(nodesock);
- #ifdef VERBOSE_NET
- std::cerr << "Connected to " << config.nodes[i].name << "\n";
- #endif
- }
- }
|