当前位置: 首页 > 工具软件 > Async Server > 使用案例 >

async_udp_echo_server.cpp

松英喆
2023-12-01
 

async_udp_echo_server.cpp

/*
 * echo server 一种非常简单的服务,它把接收到的数据原封不动地发送给客户
 * 所以客户发送什么它就会接收什么
 */


#include <cstdlib>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/asio.hpp>

//这是一个UDP实现的服务器程序
//这个程序实现体现一个重要的区别:UDP与TCP的区别
//作为无连接的UDP与作为面向连接的TCP,它们使用存在着许多不同点
using boost :: asio :: ip :: udp ;

class server
{
public :
  server (boost :: asio :: io_service & io_service, short port )
    : io_service_ (io_service ),
      socket_ (io_service, udp :: endpoint (udp :: v4 ( ), port ) )
  {
    //由于UDP是无连接的,所以我没有必要在那个地方等客户连接
    //相反我们只是在那里等着客户发送过来的数据,如果我们从一个地方收到一个数据
    //并且我们要回复这个消息,此时很简单,从哪儿来的数据,消息就回复到哪儿
    //async_receive_from 函数中的那个参数sender_endpoint就是为了这个目的,其它并不是一个输入性的函数
    //相反它是输出性的参数,async_receiv_from函数把数据据来源地放于这个参数中,
    //如下我们回复的时候就可以使用了。
    socket_. async_receive_from (
        boost :: asio :: buffer (data_, max_length ), sender_endpoint_,
        boost :: bind ( &server :: handle_receive_from, this,
          boost :: asio :: placeholders :: error,
          boost :: asio :: placeholders :: bytes_transferred ) ) ;
  }

  void handle_receive_from ( const boost :: system :: error_code & error,
      size_t bytes_recvd )
  {
    if ( !error && bytes_recvd > 0 )
    {
      //此时我们回复,回复到sender_endpiont,上次调用async_recive_from
      //会把来源地放到这里,asio的文档要求用户需要保证这个sender_endpiont
      //在上次调用之后一直到此都不有效的,本示例把它放在类型的定义中,所以
      //会一直有效
      socket_. async_send_to (
          boost :: asio :: buffer (data_, bytes_recvd ), sender_endpoint_,
          boost :: bind ( &server :: handle_send_to, this,
            boost :: asio :: placeholders :: error,
            boost :: asio :: placeholders :: bytes_transferred ) ) ;
    }
    else
    {
      socket_. async_receive_from (
          boost :: asio :: buffer (data_, max_length ), sender_endpoint_,
          boost :: bind ( &server :: handle_receive_from, this,
            boost :: asio :: placeholders :: error,
            boost :: asio :: placeholders :: bytes_transferred ) ) ;
    }
  }

  void handle_send_to ( const boost :: system :: error_code & /*error*/,
      size_t /*bytes_sent*/ )
  {
    //接收之后发送,发送之后再接收,这是由应用类型定义的,所以
    //从某种意义上与asio没有关系
    socket_. async_receive_from (
        boost :: asio :: buffer (data_, max_length ), sender_endpoint_,
        boost :: bind ( &server :: handle_receive_from, this,
          boost :: asio :: placeholders :: error,
          boost :: asio :: placeholders :: bytes_transferred ) ) ;
  }

private :
  boost :: asio :: io_service & io_service_ ;
  udp :: socket socket_ ;
  udp :: endpoint sender_endpoint_ ;
  enum { max_length = 1024 } ;
  char data_ [max_length ] ;
} ;

int main ( int argc, char * argv [ ] )
{
  try
  {
    if (argc ! = 2 )
    {
      std :: cerr << "Usage: async_udp_echo_server <port>\n" ;
      return 1 ;
    }

    boost :: asio :: io_service io_service ;

    using namespace std ; // For atoi.
    server s (io_service, atoi (argv [1 ] ) ) ;

    io_service. run ( ) ;
  }
  catch (std :: exception & e )
  {
    std :: cerr << "Exception: " << e. what ( ) << "\n" ;
  }

  return 0 ;
}
 类似资料:

相关阅读

相关文章

相关问答