C++ Boost访问TCP客户端IP地址+;连接后来自TCP服务器的端口
我已经使用BoostASIO实现了tcp客户端和tcp服务器。代码如下所示<代码>(test.cpp、test.hpp和makefile) 可执行文件可以作为C++ Boost访问TCP客户端IP地址+;连接后来自TCP服务器的端口,c++,sockets,boost,tcp,C++,Sockets,Boost,Tcp,我已经使用BoostASIO实现了tcp客户端和tcp服务器。代码如下所示(test.cpp、test.hpp和makefile) 可执行文件可以作为 (服务器端) (客户端) tcp\u服务器类在接受连接时应该知道远程端点(客户端ip地址+客户端端口地址)。 然而,似乎没有变量在服务器端存储它,我想存储客户端端点信息。我该怎么做 test.cpp #include "test.hpp" #include <iostream> #include <exception> #
(服务器端)
(客户端)
tcp\u服务器
类在接受连接时应该知道远程端点(客户端ip地址+客户端端口地址)。
然而,似乎没有变量在服务器端存储它,我想存储客户端端点信息。我该怎么做
test.cpp
#include "test.hpp"
#include <iostream>
#include <exception>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <algorithm>
#include <sstream>
#include <iomanip>
const int ARG_COUNT = 2;
const int MAX_PACKETS = 25;
const int LOWEST_PORT = 1024;
const int HIGHEST_PORT = 65000;
static char message_array[8192];
void gen_random_string(char *s, const int len)
{
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[len] = 0;
}
class tcp_connection :public boost::enable_shared_from_this<tcp_connection>
{
public:
typedef boost::shared_ptr<tcp_connection> pointer;
static pointer create(boost::asio::io_service& io_service)
{
return pointer(new tcp_connection(io_service));
}
boost::asio::ip::tcp::tcp::socket& socket()
{
return socket_;
}
void start()
{
gen_random_string(message_array, 8192);
std::string message(message_array);
boost::asio::async_write(socket_, boost::asio::buffer(message),
boost::bind(&tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
tcp_connection(boost::asio::io_service& io_service)
: socket_(io_service)
{
}
void handle_write(const boost::system::error_code& /*error*/,
size_t /*bytes_transferred*/)
{
}
boost::asio::ip::tcp::socket socket_;
std::string message;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_service& io_service,int port_number)
: acceptor_(io_service, boost::asio::ip::tcp::tcp::endpoint(boost::asio::ip::tcp::tcp::v4(), port_number))
{
std::cout << "TCP server listening on " << port_number << std::endl;
start_accept();
}
private:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_io_service());
acceptor_.async_accept(new_connection->socket(),
boost::bind(&tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
start_accept();
}
}
boost::asio::ip::tcp::tcp::acceptor acceptor_;
};
void runTCPServer ( CmdLineOpts input )
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service,input.port);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
class tcp_client
{
public:
tcp_client(
boost::asio::io_service& io_service,
const std::string& host,
const std::string& port
) : io_service_(io_service), socket_(io_service, boost::asio::ip::tcp::tcp::endpoint(boost::asio::ip::tcp::tcp::v4(), 0))
{
boost::asio::ip::tcp::tcp::resolver resolver(io_service_);
boost::asio::ip::tcp::tcp::resolver::query query(boost::asio::ip::tcp::tcp::v4(), host, port);
boost::asio::ip::tcp::tcp::resolver::iterator iter = resolver.resolve(query);
endpoint_ = *iter;
boost::asio::connect(socket_, iter);
}
~tcp_client()
{
socket_.close();
}
void recieve_from() {
/*Initialize our endpoint*/
size_t len = socket_.read_some(
boost::asio::buffer(recv_buf), error);
if (error == boost::asio::error::eof)
std::cout << "Connction close cleanly by peer" << std::cout;
else if (error)
throw boost::system::system_error(error); // Some other error.
std::cout.write(recv_buf.data(), len) << std::endl;
}
private:
boost::asio::io_service& io_service_;
boost::asio::ip::tcp::tcp::socket socket_;
boost::asio::ip::tcp::tcp::endpoint endpoint_;
boost::array<char, 2048> recv_buf;
boost::asio::ip::tcp::endpoint sender_endpoint;
boost::system::error_code error;
};
void runTCPClient(std::string portStr)
{
try
{
boost::asio::io_service io_service;
tcp_client client(io_service, "localhost", portStr);
client.recieve_from();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
void runClient( CmdLineOpts input )
{
runTCPClient(input.portStr);
}
void runServer( CmdLineOpts input )
{
runTCPServer(input);
}
/**
* * Usage: client_server <protocol> <port> <num of packets>
* */
bool cmdline_parse ( int argc, char *argv[], CmdLineOpts *input )
{
bool result = true;
if (argc - 1 == ARG_COUNT)
{
// arg 1: server or client
int arg1 = std::stoi(argv[1]);
if (arg1 == 0 || arg1 == 1)
{
input->servOrClient = arg1;
}
else
{
std::cout << "Invalid client server choice.\nUsage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
result = false;
}
// arg 3: port
int arg2 = std::stoi(argv[2]);
if (arg2 > LOWEST_PORT && arg2 < HIGHEST_PORT )
{
input->port = arg2;
input->portStr = argv[2];
}
else
{
std::cout << "Invalid port, must be between " << LOWEST_PORT << " and " << HIGHEST_PORT << std::endl;
std::cout << "Usage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
result = false;
}
}
else
{
std::cout << "Usage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
result = false;
}
return result;
}
int main ( int argc, char *argv[] )
{
CmdLineOpts input;
if (cmdline_parse(argc, argv, &input))
{
if(input.servOrClient == 1)
{
runServer(input);
}
else if(input.servOrClient == 0)
{
runClient(input);
}
}
else
{
return 1;
}
return 0;
}
#包括“test.hpp”
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
常数int ARG_COUNT=2;
const int MAX_PACKETS=25;
const int最低_端口=1024;
最高端口常数=65000;
静态字符消息_数组[8192];
void gen_random_字符串(char*s,const int len)
{
静态常量字符alphanum[]=
"0123456789"
“ABCDEFGHIJKLMNOPQRSTUVWXYZ”
“abcdefghijklmnopqrstuvwxyz”;
对于(int i=0;i std::cout您可以调用socket\uu.remote\u endpoint()
来获取它。请参阅:
$ ./client_server 0 5005
#include "test.hpp"
#include <iostream>
#include <exception>
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <algorithm>
#include <sstream>
#include <iomanip>
const int ARG_COUNT = 2;
const int MAX_PACKETS = 25;
const int LOWEST_PORT = 1024;
const int HIGHEST_PORT = 65000;
static char message_array[8192];
void gen_random_string(char *s, const int len)
{
static const char alphanum[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i) {
s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
}
s[len] = 0;
}
class tcp_connection :public boost::enable_shared_from_this<tcp_connection>
{
public:
typedef boost::shared_ptr<tcp_connection> pointer;
static pointer create(boost::asio::io_service& io_service)
{
return pointer(new tcp_connection(io_service));
}
boost::asio::ip::tcp::tcp::socket& socket()
{
return socket_;
}
void start()
{
gen_random_string(message_array, 8192);
std::string message(message_array);
boost::asio::async_write(socket_, boost::asio::buffer(message),
boost::bind(&tcp_connection::handle_write, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
private:
tcp_connection(boost::asio::io_service& io_service)
: socket_(io_service)
{
}
void handle_write(const boost::system::error_code& /*error*/,
size_t /*bytes_transferred*/)
{
}
boost::asio::ip::tcp::socket socket_;
std::string message;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_service& io_service,int port_number)
: acceptor_(io_service, boost::asio::ip::tcp::tcp::endpoint(boost::asio::ip::tcp::tcp::v4(), port_number))
{
std::cout << "TCP server listening on " << port_number << std::endl;
start_accept();
}
private:
void start_accept()
{
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.get_io_service());
acceptor_.async_accept(new_connection->socket(),
boost::bind(&tcp_server::handle_accept, this, new_connection,
boost::asio::placeholders::error));
}
void handle_accept(tcp_connection::pointer new_connection,
const boost::system::error_code& error)
{
if (!error)
{
new_connection->start();
start_accept();
}
}
boost::asio::ip::tcp::tcp::acceptor acceptor_;
};
void runTCPServer ( CmdLineOpts input )
{
try
{
boost::asio::io_service io_service;
tcp_server server(io_service,input.port);
io_service.run();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
class tcp_client
{
public:
tcp_client(
boost::asio::io_service& io_service,
const std::string& host,
const std::string& port
) : io_service_(io_service), socket_(io_service, boost::asio::ip::tcp::tcp::endpoint(boost::asio::ip::tcp::tcp::v4(), 0))
{
boost::asio::ip::tcp::tcp::resolver resolver(io_service_);
boost::asio::ip::tcp::tcp::resolver::query query(boost::asio::ip::tcp::tcp::v4(), host, port);
boost::asio::ip::tcp::tcp::resolver::iterator iter = resolver.resolve(query);
endpoint_ = *iter;
boost::asio::connect(socket_, iter);
}
~tcp_client()
{
socket_.close();
}
void recieve_from() {
/*Initialize our endpoint*/
size_t len = socket_.read_some(
boost::asio::buffer(recv_buf), error);
if (error == boost::asio::error::eof)
std::cout << "Connction close cleanly by peer" << std::cout;
else if (error)
throw boost::system::system_error(error); // Some other error.
std::cout.write(recv_buf.data(), len) << std::endl;
}
private:
boost::asio::io_service& io_service_;
boost::asio::ip::tcp::tcp::socket socket_;
boost::asio::ip::tcp::tcp::endpoint endpoint_;
boost::array<char, 2048> recv_buf;
boost::asio::ip::tcp::endpoint sender_endpoint;
boost::system::error_code error;
};
void runTCPClient(std::string portStr)
{
try
{
boost::asio::io_service io_service;
tcp_client client(io_service, "localhost", portStr);
client.recieve_from();
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
void runClient( CmdLineOpts input )
{
runTCPClient(input.portStr);
}
void runServer( CmdLineOpts input )
{
runTCPServer(input);
}
/**
* * Usage: client_server <protocol> <port> <num of packets>
* */
bool cmdline_parse ( int argc, char *argv[], CmdLineOpts *input )
{
bool result = true;
if (argc - 1 == ARG_COUNT)
{
// arg 1: server or client
int arg1 = std::stoi(argv[1]);
if (arg1 == 0 || arg1 == 1)
{
input->servOrClient = arg1;
}
else
{
std::cout << "Invalid client server choice.\nUsage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
result = false;
}
// arg 3: port
int arg2 = std::stoi(argv[2]);
if (arg2 > LOWEST_PORT && arg2 < HIGHEST_PORT )
{
input->port = arg2;
input->portStr = argv[2];
}
else
{
std::cout << "Invalid port, must be between " << LOWEST_PORT << " and " << HIGHEST_PORT << std::endl;
std::cout << "Usage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
result = false;
}
}
else
{
std::cout << "Usage: client_server <client (0) or server(1)> <protocol> <port>" << std::endl;
result = false;
}
return result;
}
int main ( int argc, char *argv[] )
{
CmdLineOpts input;
if (cmdline_parse(argc, argv, &input))
{
if(input.servOrClient == 1)
{
runServer(input);
}
else if(input.servOrClient == 0)
{
runClient(input);
}
}
else
{
return 1;
}
return 0;
}
#ifndef CLIENT_SERVER_H_INCLUDED
#define CLIENT_SERVER_H_INCLUDED
#include <string>
struct CmdLineOpts
{
std::string portStr;
int port;
int servOrClient;
};
void runTCPServer ( CmdLineOpts input );
void runTCPClient ( std::string port_str);
bool cmdline_parse ( int argc, char *argv[], CmdLineOpts input );
#endif
TARGET = client_server
LIBS = -lboost_system -lpthread
CXX = g++
CXXFLAGS = -std=c++11 -g -Wall -pedantic
.PHONY: default all clean
default: $(TARGET)
all: default
OBJECTS = $(patsubst %.cpp, %.o, $(wildcard *.cpp))
HEADERS = $(wildcard *.hpp)
%.o: %.cpp $(HEADERS)
$(CXX) $(CXXFLAGS) -c $< -o $@
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CXX) $(OBJECTS) $(LIBS) -o $@
clean:
-rm -f *.o
-rm -f $(TARGET)