ソケットを特定のポートにバインドすることは、質問に投稿されたとおりに行うことができます。
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
tcp::socket socket(io_service, tcp::endpoint(tcp::v4(), 2000));
assert(socket.local_endpoint().port() == 2000); // true
この場合、socket
オブジェクトが構築され、開かれ、アドレスとポートを持つローカルエンドポイントにバインドされます。INADDR_ANY
2000
ローカル エンドポイントは、接続の確立方法の結果として変化している可能性があります。接続操作がsocket.connect()
またはsocket.async_connect()
メンバー関数のいずれかから開始されると、ソケットはリモート エンドポイントへの接続を試み、必要に応じてソケットを開きます。したがって、すでに開いているソケットで呼び出された場合、ソケットのローカル エンドポイントは変更されません。
一方、いずれかconnect()
またはasync_connect()
free 関数から接続操作が開始されると、エンドポイントへの接続を試行する前にソケットが閉じられます。したがって、ソケットは未指定のポートにバインドされます。フリー関数のドキュメントのパラメーター セクションでは、この動作が定義されています。
socket
接続する。がすでに開いている場合は、socket
閉じられます。
socket.close()
さらに、およびメンバー関数がimplementationsocket.connect()
内で次々に呼び出されるため、この動作を制御する明確な方法はありません。
上記の動作を示す完全な例を次に示します。
#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
// This example is not interested in the handlers, so provide a noop function
// that will be passed to bind to meet the handler concept requirements.
void noop() {}
// Helper function used to initialize the client socket.
void force_endpoint(boost::asio::ip::tcp::socket& client_socket)
{
using boost::asio::ip::tcp;
client_socket.close();
client_socket.open(tcp::v4());
client_socket.bind(tcp::endpoint(tcp::v4(), 2000));
std::cout << "client socket: " << client_socket.local_endpoint()
<< std::endl;
}
int main()
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
// Create all I/O objects.
tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 0));
tcp::socket server_socket(io_service);
tcp::socket client_socket(io_service);
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initiate the connect operation directly on the socket.
server_socket.close();
force_endpoint(client_socket);
acceptor.async_accept(server_socket, boost::bind(&noop));
client_socket.async_connect(acceptor.local_endpoint(), boost::bind(&noop));
// Print endpoints before and after running the operations.
io_service.run();
std::cout << "After socket.async_connect(): "
<< client_socket.local_endpoint() << std::endl;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Initiate the connection operation with the free async_connect function.
server_socket.close();
force_endpoint(client_socket);
acceptor.async_accept(server_socket, boost::bind(&noop));
boost::asio::async_connect(
client_socket,
tcp::resolver(io_service).resolve(
tcp::resolver::query("127.0.0.1",
boost::lexical_cast<std::string>(acceptor.local_endpoint().port()))),
boost::bind(&noop));
// Run the service, causing the client to connect to the acceptor.
io_service.reset();
io_service.run();
std::cout << "After async_connect(): "
<< client_socket.local_endpoint() << std::endl;
}
次の出力が生成されました。
client socket: 0.0.0.0:2000
After socket.async_connect(): 127.0.0.1:2000
client socket: 0.0.0.0:2000
After async_connect(): 127.0.0.1:53115