【问题标题】:SCTP Server using boost.asio使用 boost.asio 的 SCTP 服务器
【发布时间】:2023-02-14 00:45:11
【问题描述】:

我正在尝试使用 boost.asio 框架实现 sctp 客户端-服务器模型。 目前我有这个服务器:

#include <boost/asio.hpp>
#include <iostream>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>
using namespace boost;


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


    if (argc < 2){
        exit(0);
    }
    unsigned short MY_PORT_NUM = atoi(argv[1]);
    struct sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    servaddr.sin_port = htons(MY_PORT_NUM);


    try {
        asio::io_context io_service;
        boost::asio::generic::seq_packet_protocol::endpoint endpoint((struct sockaddr *)&servaddr, sizeof(servaddr),IPPROTO_SCTP);
        boost::asio::basic_socket_acceptor<asio::generic::seq_packet_protocol> acceptor(io_service,endpoint);
        boost::system::error_code ec;
        asio::generic::seq_packet_protocol::socket socket(io_service);
        acceptor.accept(socket,ec);
        if (ec){
          std::cout << ec.message() << "\n";
        } 
                

    } catch ( boost::system::error_code& e){
        std::cerr << e.message() << std::endl;
    }
    return 0;
}

我收到一条错误消息“不支持操作”。 我也试过这样做:


    try {

        asio::io_context io_service;
        boost::asio::generic::seq_packet_protocol p(AF_INET,IPPROTO_SCTP);
        boost::asio::generic::seq_packet_protocol::endpoint endpoint((struct sockaddr *)&servaddr, sizeof(servaddr),IPPROTO_SCTP);
        boost::asio::basic_socket_acceptor<asio::generic::seq_packet_protocol> acceptor(io_service);
        acceptor.open(p);
        acceptor.bind(endpoint);
        acceptor.listen();
      
        boost::system::error_code ec;
        asio::generic::seq_packet_protocol::socket socket(io_service);
        acceptor.accept(socket,ec);

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


    } catch ( boost::system::error_code& e){
        std::cerr << e.message() << std::endl;
    }

我得到了完全相同的结果。
您可以使用以下代码编译此代码:
g++ sctp_server.cc -o sctp_server -lboost_thread -lboost_coroutine
我有 C 版本的 sctp 服务器,它工作正常:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <libgen.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <netinet/sctp.h>
#include <arpa/inet.h>

static void die(const char *s) {
        perror(s);
        exit(1);
}
static void server(unsigned short port){
    
    struct sockaddr_in servaddr;
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(port);

    struct sctp_initmsg initmsg;
    initmsg.sinit_max_attempts = 4;
    initmsg.sinit_num_ostreams = 5;
    initmsg.sinit_num_ostreams = 5;

    int listen_fd = socket(AF_INET, SOCK_STREAM,IPPROTO_SCTP);
    if (listen_fd < 0)
        die("socket()");
    if ( bind(listen_fd, (struct sockaddr *)&servaddr,sizeof(servaddr)) < 0)
        die("bind()");
    if ( setsockopt(listen_fd,IPPROTO_SCTP,SCTP_INITMSG,&initmsg,sizeof(initmsg)) < 0)
        die("setsockopt()");
    if ( listen(listen_fd,initmsg.sinit_max_instreams) < 0)
        die("listen()");

    for (;;){
        char buffer[1024];
        fputs("Waiting for connection\n",stdout);
        
        int connect_fd = accept(listen_fd, (struct sockaddr *)NULL, NULL);
        if (connect_fd < 0)
            die("accept()");

        fputs("New client connected\n",stdout);
         struct sctp_sndrcvinfo sndrcvinfo;
         int flags;
        size_t bytesRcvd = sctp_recvmsg(connect_fd,buffer,sizeof(buffer),NULL,0,&sndrcvinfo,&flags);
        if (bytesRcvd > 0){
            printf("Received data : %s\n", buffer);
        }
        close(connect_fd);
    }

}
int main(int argc, char * argv[]){
    if (argc < 2)
        die("Usage ./c_sctp_server <Port>");

    unsigned short port = atoi(argv[1]);
    server(port);
    return 0;
}

你可以编译它:
gcc c_sctp_server.c -o c_sctp_server -lsctp
问题是我的 boost.asio 版本有什么问题?

【问题讨论】:

    标签: c++ boost-asio


    【解决方案1】:

    首先,error_code 从未被提出过。你可能想抓住system_error

    } catch (boost::system::system_error const& e) {
        std::cerr << e.code().message() << " from " << e.code().location() << std::endl;
    }
    

    请注意,您通常可以了解错误的来源位置,如图所示。在您的情况下(略有编辑):

    Operation not supported from boost/asio/detail/reactive_socket_service.hpp:505:5 in function 'error_code reactive_socket_service<Protocol>::accept(implementation_type&, Socket&, endpoint_type*, error_code&)'
    

    如消息所示,seq_packet_protocol 不支持accept。我认为你将从generic::stream_protocol开始获得更多杠杆了解连接(SCTP 的“关联”)。

    您还可以考虑从现有的 POSIX SCTP example 开始,并逐渐用 Asio 替换位。

    免责声明:我不熟悉 SCTP。随意浏览 RFC 9260 让我觉得适应起来并非易事,因为行为非常不同(例如更改关联或对等地址),即使假设您将直接使用 POSIX API 而不是包装特定于 SCTP 的套接字选项。

    【讨论】:

      猜你喜欢
      • 2014-10-27
      • 1970-01-01
      • 1970-01-01
      • 2018-03-14
      • 2012-12-14
      • 1970-01-01
      • 1970-01-01
      • 2023-02-01
      • 2018-03-09
      相关资源
      最近更新 更多