1

I write my own function named asyncAccept to encapsulate the standard boost::asio::ip::acceptor::async_accept, but problems occurred when I run my program. An error was thrown and it prints "argument invalid". It seems that the expression has something wrong:

boost::bind(handle_accept, placeholders::error, socket, tcp_version, port_num, handler));

I wonder what's the problem. Complete codes are attached below. My mother tongue is not English, so please be patient a bit~~ Thanks a lot in advance!

----------------------------------------asyncAccept.cpp-------------------------------
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include "impl/asyncAccept.h"

using namespace boost::asio;

namespace asyncTcp{

error_type illegal_version = -1;
error_type accept_error = -2;
const int TCPV4 = 4;
const int TCPV6 = 6;

io_service io_server;
ip::tcp::acceptor _acceptor(io_server);

ip::tcp::socket _socket(io_server);
void *servSocket = &_socket;

void handle_accept(const boost::system::error_code& error, void* socketPtr, const int tcp_version, unsigned short port_num, callback handler);

void init_acceptor(const int tcp_version, unsigned short port_num);

//bind a socket with a port
void asyncAccept(void* socketPtr, const int tcp_version, unsigned short port_num, callback handler){

    if (tcp_version != TCPV4 && tcp_version != TCPV6)
        throw illegal_version;

    init_acceptor(tcp_version, port_num);

    ip::tcp::socket *socket = reinterpret_cast<ip::tcp::socket*>(socketPtr);

    _acceptor.async_accept((*socket),
        boost::bind(handle_accept, placeholders::error, socket, tcp_version, port_num, handler));

    return;
}

void handle_accept(const boost::system::error_code& error, void* socketPtr, const int tcp_version, unsigned short port_num, callback handler){
    if (!error){
        //cycle server
        handler();

        asyncAccept(socketPtr, tcp_version, port_num, handler);
    }
    else
        throw boost::system::system_error(error);
}

void init_acceptor(const int tcp_version, unsigned short port_num){
    if (TCPV4 == tcp_version){
        ip::tcp::endpoint ep(ip::tcp::v4(), port_num);
        _acceptor.open(ip::tcp::v4());
        _acceptor.bind(ep);
    }
    else{
        ip::tcp::endpoint ep(ip::tcp::v6(), port_num);
        _acceptor.open(ip::tcp::v6());
        _acceptor.bind(ep);
    }
}

void run_server(){
    io_server.run();

    return;
}

}//namespace



-----------------------------------impl/asyncAccept.h----------------------------------
#ifndef SERV_SOCKET_H
#define SERV_SOCKET_H

namespace asyncTcp{

#ifndef CALL_BACK
#define CALL_BACK
typedef void (*callback)();
#endif

#ifndef ERROR_TYPE
#define ERROR_TYPE
typedef int error_type;
#endif

extern error_type illegal_version;
extern error_type accept_error;
//extern void* io_server;
extern void* servSocket;
extern const int TCPV4;
extern const int TCPV6;

void asyncAccept(void* socketPtr, const int tcp_version, unsigned short port_num, callback handler);

void run_server();
}

#endif /* SERV_SOCKET_H */
4

1 回答 1

3

You have to put the boost::asio::ip::tcp::acceptor into the listen state. This can be done by calling boost::asio::ip::tcp::listen(). Like this:

void init_acceptor(const int tcp_version, unsigned short port_num){
    if (TCPV4 == tcp_version){
        ip::tcp::endpoint ep(ip::tcp::v4(), port_num);
        _acceptor.open(ip::tcp::v4());
        _acceptor.bind(ep);
    }
    else{
        ip::tcp::endpoint ep(ip::tcp::v6(), port_num);
        _acceptor.open(ip::tcp::v6());
        _acceptor.bind(ep);
    }
    _acceptor.listen();
}

Explanation: If the server socket is not in listen state when calling the underlying accept(..) function of the socket API, an error is signaled, that the passed socket is not valid for finishing the requested operation (in our case accept a client socket).

于 2013-05-13T12:40:31.707 回答