欢迎光临散文网 会员登陆 & 注册

Boost.Asio

2023-03-14 21:44 作者:小粉丝8  | 我要投稿



# Makefile for top dir

# $(call makever,1.2.3)

# major.minor.patch

# libtool manual: -version-number

define makever

  @ $(MAKE) -C $@ soname=lib$@.so.$(word 1,$(subst ., ,$(1)))

  @ cp $(OBJDIR)/$@/$@ $(OBJDIR)/$@/lib$@.so.$(1)

  @ cd $(OBJDIR)/$@ ; \

    ln -f -s lib$@.so.$(1) lib$@.so.$(word 1,$(subst ., ,$(1))) ; \

    cd - >/dev/null 2>&1 ;

  @ cd $(OBJDIR)/$@ ; \

    ln -f -s lib$@.so.$(1) lib$@.so ; \

    cd - >/dev/null 2>&1 ;

endef

# make # BUILD_DIR=build

ifdef BUILD_DIR

export OBJDIR = $(abspath $(BUILD_DIR))

else

export OBJDIR = $(abspath build)

endif

SUBDIRS = main # foo

all : $(SUBDIRS)

install : $(SUBDIRS)

$(SUBDIRS) : | $(OBJDIR)

$(OBJDIR) : ; @ mkdir $@

# main : foo

main : ; @ $(MAKE) -C $@

# foo : ; $(call makever,1.2.3)

# make DESTDIR=~/foo install

# Alexandre Duret-Lutz's Autotools Tutorial (without animations):

# "is ready to be uncompressed in / on many hosts"

install :

  install -d $(DESTDIR)/usr/local/bin

  install -d $(DESTDIR)/usr/local/lib

  install -m 0755 $(OBJDIR)/main/server $(DESTDIR)/usr/local/bin

  install -m 0755 $(OBJDIR)/main/client $(DESTDIR)/usr/local/bin

  # cp -P $(OBJDIR)/foo/*.so* $(DESTDIR)/usr/local/lib

clean :

  @ for dir in $(SUBDIRS); do \

    $(MAKE) -C $$dir $@; \

  done

  -rm -fr $(OBJDIR)

.PHONY : $(SUBDIRS) all install clean

---

# Makefile for subdir

# build shared library with -fPIC, -shared

CXXFLAGS  = # -g -O3 -fPIC # CXXFLAGS for .cpp

CPPFLAGS  = -MMD -MP -I/home/ljh/Downloads/boost_1_81_0/ # -I../foo

LDFLAGS   = -L/home/ljh/Downloads/boost_1_81_0/stage/lib # -L$(OBJDIR)/foo # -shared

LDLIBS    = -lpthread

# CC      = $(CXX) # link with CXX for .cpp

LDFLAGS  += -Wl,-rpath,'$$ORIGIN/../foo'

LDFLAGS  += -Wl,-rpath,'$$ORIGIN/../lib'

#LDFLAGS += -Wl,-soname,$(soname)

# make # NDEBUG=1

ifdef NDEBUG

CXXFLAGS += -O3 # .cpp

CPPFLAGS += -DNDEBUG

else

CXXFLAGS += -g # .cpp

LDFLAGS  += -fsanitize=address

endif

SUBDIR    = $(OBJDIR)/$(lastword $(subst /, ,$(CURDIR)))

all : $(SUBDIR)/server $(SUBDIR)/client

# https://make.mad-scientist.net/papers/how-not-to-use-vpath/

# $(SUBDIR)/main : $(addprefix $(SUBDIR)/,$(patsubst %.c,%.o,$(wildcard *.c))) # .cpp

#   $(CC) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(SUBDIR)/server : $(addprefix $(SUBDIR)/,$(patsubst %.cpp,%.o,server.cpp)) # .cpp

  $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(SUBDIR)/client : $(addprefix $(SUBDIR)/,$(patsubst %.cpp,%.o,client.cpp)) # .cpp

  $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

$(SUBDIR)/%.o : %.cpp | $(SUBDIR) # .cpp

  $(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<

$(SUBDIR) : ; @ mkdir $@

-include $(SUBDIR)/*.d

clean : ; -rm -fr $(SUBDIR)

.PHONY : all clean

---

// ./boost_1_81_0/doc/html/boost_asio/example/cpp11/echo/async_tcp_echo_server.cpp

#include <cstdlib>

#include <iostream>

#include <memory>

#include <utility>

#include <boost/asio.hpp>

#ifndef NDEBUG

#include <sanitizer/lsan_interface.h>

#endif

struct session

  : public std::enable_shared_from_this<session>

{

  session(boost::asio::ip::tcp::socket socket)

    : socket(std::move(socket))

  { }

  void start() {

    start_read();

    start_write();

  }

  void start_read() {

    auto self(shared_from_this());

    memset(input_data, 0, sizeof(input_data));

    socket.async_read_some(

      boost::asio::buffer(input_data, sizeof(input_data)),

      [&, self](boost::system::error_code ec, std::size_t length) {

        if (!ec) {

          std::cout << input_data;

          start_read();

        } else {

          std::cout << ec.message() << "\n";

        }

      }

    );

  }

  void start_write() {

    auto self(shared_from_this());

    memset(output_data, 0, sizeof(output_data));

    snprintf(output_data, sizeof(output_data) - 1,

      "hello client %zu\n", cnt++);

    boost::asio::async_write(

      socket,

      boost::asio::buffer(output_data, sizeof(input_data)),

      [&, self](boost::system::error_code ec, std::size_t length)

      {

        if (!ec) {

          // sleep(1); //test

          start_write();

        } else {

          std::cout << ec.message() << "\n";

        }

      }

    );

  }

  boost::asio::ip::tcp::socket socket;

  enum { LEN = 1024 };

  char input_data[LEN];

  char output_data[LEN];

  size_t cnt = 0;

};

struct server {

  server(boost::asio::io_context& io_context, short port)

    : acceptor(io_context, boost::asio::ip::tcp::endpoint(

        boost::asio::ip::tcp::v4(), port))

  {

    std::cout << "Listen on port: " << port << " \n";

    do_accept();

  }

  void do_accept() {

    acceptor.async_accept(

      [&](boost::system::error_code ec,

        boost::asio::ip::tcp::socket socket)

      {

        if (!ec) {

          std::cout << "Accept connection: "

            << socket.remote_endpoint() << "\n";

          std::make_shared<session>(std::move(socket))->start();

        } else {

          std::cout << ec.message() << "\n";

        }

        do_accept();

      }

    );

  }

  boost::asio::ip::tcp::acceptor acceptor;

};

void handlerCont(int signum) {

  printf("SIGCONT %d\n", signum);

#ifndef NDEBUG

  __lsan_do_recoverable_leak_check();

#endif

}

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

  if (argc != 2) {

    std::cerr << "Usage: server <port>\n";

    return 1;

  }

  signal(SIGCONT, handlerCont); // kill -CONT 123 # pid

  boost::asio::io_context io_context;

  server s(io_context, std::atoi(argv[1]));

  io_context.run();

  return 0;

}

---

// ./boost_1_81_0/doc/html/boost_asio/example/cpp11/timeouts/async_tcp_client.cpp

#include <boost/asio/buffer.hpp>

#include <boost/asio/io_context.hpp>

#include <boost/asio/ip/tcp.hpp>

#include <boost/asio/write.hpp>

#include <iostream>

#include <string>

#ifndef NDEBUG

#include <sanitizer/lsan_interface.h>

#endif

std::string client_tag; //test

struct session

  : public std::enable_shared_from_this<session>

{

  session(boost::asio::ip::tcp::socket socket)

    : socket(std::move(socket))

  { }

  void start() {

    start_read();

    start_write();

  }

  void start_read() {

    auto self(shared_from_this());

    memset(input_data, 0, sizeof(input_data));

    socket.async_read_some(

      boost::asio::buffer(input_data, sizeof(input_data)),

      [&, self](boost::system::error_code ec, std::size_t length) {

        if (!ec) {

          std::cout << input_data;

          start_read();

        } else {

          std::cout << ec.message() << "\n";

        }

      }

    );

  }

  void start_write() {

    auto self(shared_from_this());

    memset(output_data, 0, sizeof(output_data));

    snprintf(output_data, sizeof(output_data) - 1,

      "hello server %s %zu\n", client_tag.c_str(), cnt++);

    boost::asio::async_write(

      socket,

      boost::asio::buffer(output_data, sizeof(input_data)),

      [&, self](boost::system::error_code ec, std::size_t length)

      {

        if (!ec) {

          // sleep(1); //test

          start_write();

        } else {

          std::cout << ec.message() << "\n";

        }

      }

    );

  }

  boost::asio::ip::tcp::socket socket;

  enum { LEN = 1024 };

  char input_data[LEN];

  char output_data[LEN];

  size_t cnt = 0;

};

struct client {

  client(boost::asio::io_context& io_context,

    boost::asio::ip::tcp::resolver::results_type endpoints)

      : socket(io_context), endpoints(endpoints)

  {

    do_connect(endpoints.begin());

  }

  void do_connect (

    boost::asio::ip::tcp::resolver::results_type::iterator

    endpoint_iter)

  {

    if (endpoint_iter != endpoints.end()) {

      socket.async_connect(

        endpoint_iter->endpoint(),

        [&](const boost::system::error_code ec)

        {

          if (!socket.is_open()) {

            std::cout << "Connect timed out\n";

            do_connect(++endpoint_iter);

          } else if (ec) {

            std::cout << "Connect error: " << ec.message() << "\n";

            socket.close();

          } else {

            std::cout << "Connected to " <<

              socket.remote_endpoint() << "\n";

            std::make_shared<session>(std::move(socket))->start();

          }

        }

      );

    }

  }

  boost::asio::ip::tcp::resolver::results_type endpoints;

  boost::asio::ip::tcp::socket socket;

};

void handlerCont(int signum){

  printf("SIGCONT %d\n", signum);

#ifndef NDEBUG

  __lsan_do_recoverable_leak_check();

#endif

}

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

  if (argc != 4) {

    std::cerr << "Usage: client <host> <port> <tag>\n";

    return 1;

  }

  signal(SIGCONT, handlerCont); // kill -CONT 123 # pid

  client_tag = argv[3];

  boost::asio::io_context io_context;

  boost::asio::ip::tcp::resolver r(io_context);

  client c(io_context, r.resolve(argv[1], argv[2]));

  io_context.run();

  return 0;

}


Boost.Asio的评论 (共 条)

分享到微博请遵守国家法律