boost.asio
来源:互联网 发布:水手怕水 知乎 编辑:程序博客网 时间:2024/05/16 15:48
Asio学习1: TCP客户端:对准时间 解析
#include <iostream>
#include <boost/array.hpp>
#include <boost/asio.hpp>
//本程序的目的是访问一个时间同步服务器,我们需要用户指定一个服务器(如time-a.nist.gov),用IP亦可.
using boost::asio::ip::tcp;
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr << "Usage: client <host>" << std::endl;
return 1;
}
//用asio进行网络连接至少需要一个boost::asio::io_service对象
boost::asio::io_service io_service;
/*
我们需要把在命令行参数中指定的服务器转换为TCP上的节点.
完成这项工作需要boost::asio::ip::tcp::resolver对象
*/
tcp::resolver resolver(io_service);
/*
一个resolver对象查询一个参数,并将其转换为TCP上节点的列表.
这里我们把argv[1]中的sever的名字和要查询字串daytime关联.
*/
tcp::resolver::query query(argv[1], "daytime");
/*
节点列表可以用 boost::asio::ip::tcp::resolver::iterator 来进行迭代.
iterator默认的构造函数生成一个end iterator.
*/
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
/*
现在我们建立一个连接的sockert,由于获得节点既有IPv4也有IPv6的.
所以,我们需要依次尝试他们直到找到一个可以正常工作的.这步使得我们的程序独立于IP版本
*/
tcp::socket socket(io_service);
boost::asio::error error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator++, boost::asio::assign_error(error));
}
if (error)
throw error;
/*
连接完成,我们需要做的是读取daytime服务器的响应.
我们用boost::array来保存得到的数据,boost::asio::buffer()会自动根据array的大小暂停工作,
来防止缓冲溢出.除了使用boost::array,也可以使用char [] 或std::vector.
*/
for (;;)
{
boost::array<char, 128> buf;
boost::asio::error error;
size_t len = socket.read_some(
boost::asio::buffer(buf), boost::asio::assign_error(error));
/*
当服务器关闭连接时,boost::asio::ip::tcp::socket::read_some()会用boost::asio::error::eof标志完成,
这时我们应该退出读取循环了.
*/
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw error; // Some other error.
std::cout.write(buf.data(), len);
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
#include <boost/array.hpp>
#include <boost/asio.hpp>
//本程序的目的是访问一个时间同步服务器,我们需要用户指定一个服务器(如time-a.nist.gov),用IP亦可.
using boost::asio::ip::tcp;
int main(int argc, char* argv[])
{
try
{
if (argc != 2)
{
std::cerr << "Usage: client <host>" << std::endl;
return 1;
}
//用asio进行网络连接至少需要一个boost::asio::io_service对象
boost::asio::io_service io_service;
/*
我们需要把在命令行参数中指定的服务器转换为TCP上的节点.
完成这项工作需要boost::asio::ip::tcp::resolver对象
*/
tcp::resolver resolver(io_service);
/*
一个resolver对象查询一个参数,并将其转换为TCP上节点的列表.
这里我们把argv[1]中的sever的名字和要查询字串daytime关联.
*/
tcp::resolver::query query(argv[1], "daytime");
/*
节点列表可以用 boost::asio::ip::tcp::resolver::iterator 来进行迭代.
iterator默认的构造函数生成一个end iterator.
*/
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
/*
现在我们建立一个连接的sockert,由于获得节点既有IPv4也有IPv6的.
所以,我们需要依次尝试他们直到找到一个可以正常工作的.这步使得我们的程序独立于IP版本
*/
tcp::socket socket(io_service);
boost::asio::error error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator++, boost::asio::assign_error(error));
}
if (error)
throw error;
/*
连接完成,我们需要做的是读取daytime服务器的响应.
我们用boost::array来保存得到的数据,boost::asio::buffer()会自动根据array的大小暂停工作,
来防止缓冲溢出.除了使用boost::array,也可以使用char [] 或std::vector.
*/
for (;;)
{
boost::array<char, 128> buf;
boost::asio::error error;
size_t len = socket.read_some(
boost::asio::buffer(buf), boost::asio::assign_error(error));
/*
当服务器关闭连接时,boost::asio::ip::tcp::socket::read_some()会用boost::asio::error::eof标志完成,
这时我们应该退出读取循环了.
*/
if (error == boost::asio::error::eof)
break; // Connection closed cleanly by peer.
else if (error)
throw error; // Some other error.
std::cout.write(buf.data(), len);
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
}
注:下面这一段如果看起来有点麻烦的话可以写简单些,就让其只解析ipv4类型地址,端口号为13,只连接一次
tcp::resolver::query query(argv[1], "daytime");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
tcp::socket socket(io_service);
boost::asio::error error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator, boost::asio::assign_error(error));
}
if (error)
throw error;
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
tcp::resolver::iterator end;
tcp::socket socket(io_service);
boost::asio::error error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
socket.close();
socket.connect(*endpoint_iterator, boost::asio::assign_error(error));
}
if (error)
throw error;
简单点的:
//域名解析,只将域名解析为ipv4地址
tcp::resolver::query query(tcp::v4(),argv[1], "13");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
//只连接一次
tcp::socket socket(io_service);
boost::asio::error error = boost::asio::error::host_not_found;
socket.connect(*endpoint_iterator, boost::asio::assign_error(error));
if (error)
throw error;
tcp::resolver::query query(tcp::v4(),argv[1], "13");
tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
//只连接一次
tcp::socket socket(io_service);
boost::asio::error error = boost::asio::error::host_not_found;
socket.connect(*endpoint_iterator, boost::asio::assign_error(error));
if (error)
throw error;
下面是用winsock api(阻塞模式) 所写的代码,可以比较一下
#include <iostream>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
if(argc<2)
{
std::cout << "usage: tcp_datatime hostname(time-a.nist.gov) " << std::endl;
return -1;
}
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
std::cout << " lib error ";
return -1;
}
SOCKET cliSocket;
cliSocket = socket(AF_INET, SOCK_STREAM,0);
SOCKADDR_IN addr;
memset(&addr,0, sizeof(addr));
addr.sin_port = htons(13);
addr.sin_family = AF_INET;
if( (addr.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE)
{
hostent * hostent;
hostent = gethostbyname(argv[1]);
if(hostent == NULL)
{
std::cout << " can't resolve host! " ;
return -1;
}
memcpy(&addr.sin_addr,hostent->h_addr_list[0],4);
}
if( connect(cliSocket, (sockaddr*)&addr,sizeof(sockaddr)) != 0)
{
std::cout << "connect error ";
return -1;
}
char buf[100];
int recvSize = recv(cliSocket, buf, sizeof(buf), 0);
buf[recvSize] = 0;
std::cout << buf << std::endl;
return 0;
}
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
int main(int argc, char* argv[])
{
if(argc<2)
{
std::cout << "usage: tcp_datatime hostname(time-a.nist.gov) " << std::endl;
return -1;
}
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
std::cout << " lib error ";
return -1;
}
SOCKET cliSocket;
cliSocket = socket(AF_INET, SOCK_STREAM,0);
SOCKADDR_IN addr;
memset(&addr,0, sizeof(addr));
addr.sin_port = htons(13);
addr.sin_family = AF_INET;
if( (addr.sin_addr.s_addr = inet_addr(argv[1])) == INADDR_NONE)
{
hostent * hostent;
hostent = gethostbyname(argv[1]);
if(hostent == NULL)
{
std::cout << " can't resolve host! " ;
return -1;
}
memcpy(&addr.sin_addr,hostent->h_addr_list[0],4);
}
if( connect(cliSocket, (sockaddr*)&addr,sizeof(sockaddr)) != 0)
{
std::cout << "connect error ";
return -1;
}
char buf[100];
int recvSize = recv(cliSocket, buf, sizeof(buf), 0);
buf[recvSize] = 0;
std::cout << buf << std::endl;
return 0;
}
Asio学习2: TCP服务器端:对准时间 解析
#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std;
time_t now = time(0);
return ctime(&now);
}
int _tmain(int argc, _TCHAR* argv[])
{
try
{
boost::asio::io_service io_service;
//新建一个asio::ip::tcp::acceptor对象来监听新的连接.我们监听TCP端口13,IP版本为V4
/*
*以下构造函数相当于以下步骤
* basic_socket_acceptor<tcp> acceptor(io_service);
* acceptor.open(tcp::v4());
* acceptor.bind(tcp::endpoint(13));
* acceptor.listen(0);//default
*/
tcp::acceptor acceptor(io_service,tcp::endpoint(tcp::v4(), 13));
//basic_endpoint(const Protocol& protocol, unsigned short port_num)
//此构造函数一般作为服务器接受连接使用,ip地址即为INADDR_ANY
//这是一个iterative server,也就是说同一时间只能处理一个连接.
//建立一个socket来表示一个和客户端的连接, 然后等待客户端的连接
for(;;)
{
tcp::socket socket(io_service);
acceptor.accept(socket);
std::string message = make_daytime_string();
boost::asio::write(socket,boost::asio::buffer(message),
boost::asio::transfer_all(),boost::asio::ignore_error());
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
#include <iostream>
#include <string>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std;
time_t now = time(0);
return ctime(&now);
}
int _tmain(int argc, _TCHAR* argv[])
{
try
{
boost::asio::io_service io_service;
//新建一个asio::ip::tcp::acceptor对象来监听新的连接.我们监听TCP端口13,IP版本为V4
/*
*以下构造函数相当于以下步骤
* basic_socket_acceptor<tcp> acceptor(io_service);
* acceptor.open(tcp::v4());
* acceptor.bind(tcp::endpoint(13));
* acceptor.listen(0);//default
*/
tcp::acceptor acceptor(io_service,tcp::endpoint(tcp::v4(), 13));
//basic_endpoint(const Protocol& protocol, unsigned short port_num)
//此构造函数一般作为服务器接受连接使用,ip地址即为INADDR_ANY
//这是一个iterative server,也就是说同一时间只能处理一个连接.
//建立一个socket来表示一个和客户端的连接, 然后等待客户端的连接
for(;;)
{
tcp::socket socket(io_service);
acceptor.accept(socket);
std::string message = make_daytime_string();
boost::asio::write(socket,boost::asio::buffer(message),
boost::asio::transfer_all(),boost::asio::ignore_error());
}
}
catch (std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
下面是winsock api 所写:
#include <iostream>
#include <string>
#include <ctime>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
std::string make_daytime_string()
{
using namespace std;
time_t now = time(0);
return ctime(&now);
}
int main(int argc, char* argv[])
{
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
std::cout << " lib error ";
return -1;
}
SOCKET listenSocket;
if((listenSocket = socket(AF_INET, SOCK_STREAM,0)) == INVALID_SOCKET)
{
std::cout << "socket error ";
return -1;
}
SOCKADDR_IN addr;
memset(&addr,0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(13);
addr.sin_addr.s_addr = htonl(ADDR_ANY);
if(bind(listenSocket,(sockaddr*)&addr,sizeof(addr)) == SOCKET_ERROR)
{
std::cout << "bind error ";
}
listen(listenSocket,5);
for(;;)
{
SOCKET socket = accept(listenSocket,0,0);
std::string timeStr = make_daytime_string();
send(socket,timeStr.c_str(),timeStr.length(),0);
#include <string>
#include <ctime>
#include <winsock2.h>
#pragma comment(lib,"ws2_32.lib")
std::string make_daytime_string()
{
using namespace std;
time_t now = time(0);
return ctime(&now);
}
int main(int argc, char* argv[])
{
WSADATA wsaData;
if(WSAStartup(MAKEWORD(2,2),&wsaData) != 0)
{
std::cout << " lib error ";
return -1;
}
SOCKET listenSocket;
if((listenSocket = socket(AF_INET, SOCK_STREAM,0)) == INVALID_SOCKET)
{
std::cout << "socket error ";
return -1;
}
SOCKADDR_IN addr;
memset(&addr,0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(13);
addr.sin_addr.s_addr = htonl(ADDR_ANY);
if(bind(listenSocket,(sockaddr*)&addr,sizeof(addr)) == SOCKET_ERROR)
{
std::cout << "bind error ";
}
listen(listenSocket,5);
for(;;)
{
SOCKET socket = accept(listenSocket,0,0);
std::string timeStr = make_daytime_string();
send(socket,timeStr.c_str(),timeStr.length(),0);
closesocket(socket);
}
}
}
}
#include <ctime>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std;
time_t now = time(0);
return ctime(&now);
}
/*
从enable_shared_from_this 派生的类,
成员函数shared_from_this返回shared_ptr
tcp_connection类管理新连接的socket,连接后发送时间字符串至客户端
*/
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));
}
tcp::socket& socket()
{
return socket_;
}
void start()
{
message_ = make_daytime_string();
/*
*向新连接socket异步写数据
*注意bind的用法(可以查看有关资料),这里是绑定类成员函数
*第一个参数是类成员函数地址,第二个是该类变量指针或智能指针或类变量
*后面是传递给类成员函数的各个参数,有几个就传递几个
*/
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::asio::error&/*error*/,
size_t/*bytes_transferfed*/)
{
}
tcp::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_service& io)
: acceptor_(io, tcp::endpoint(tcp::v4(),13))
{
start_accept();
}
private:
void start_accept()
{
//创建新tcp_connection对象,成员变量socket_将会作为acceptor的参数
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.io_service());
//等待接受新连接
acceptor_.async_accept(new_connection->socket(),
boost::bind(&tcp_server::handle_accept,this,
new_connection,boost::asio::placeholders::error));
}
/*
*当async_accept接受新连接完成后呼叫handle_accept
*我们在这个函数中响应客户请求,并等待下个连接
*/
void handle_accept(tcp_connection::pointer new_connection,
boost::asio::error&error)
{
if(!error)
{
new_connection->start();
start_accept();
}
}
private:
/*
/// TCP socket 类型.
typedef basic_stream_socket<tcp> socket;
/// TCP acceptor 类型.
typedef basic_socket_acceptor<tcp> acceptor;
*/
tcp::acceptor acceptor_;
};
/*
io_service 类为异步i/o对象的用户提供核心 i/o功能(在windows2000以上环境使用完成端口)
如:
boost::asio::ip::tcp::socket
boost::asio::ip::tcp::acceptor
boost::asio::ip::udp::socket
boost::asio::deadline_timer
*/
int _tmain(int argc, _TCHAR* argv[])
{
try{
boost::asio::io_service io;
tcp_server server(io);
io.run();
}
catch(std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
#include <iostream>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
std::string make_daytime_string()
{
using namespace std;
time_t now = time(0);
return ctime(&now);
}
/*
从enable_shared_from_this 派生的类,
成员函数shared_from_this返回shared_ptr
tcp_connection类管理新连接的socket,连接后发送时间字符串至客户端
*/
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));
}
tcp::socket& socket()
{
return socket_;
}
void start()
{
message_ = make_daytime_string();
/*
*向新连接socket异步写数据
*注意bind的用法(可以查看有关资料),这里是绑定类成员函数
*第一个参数是类成员函数地址,第二个是该类变量指针或智能指针或类变量
*后面是传递给类成员函数的各个参数,有几个就传递几个
*/
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::asio::error&/*error*/,
size_t/*bytes_transferfed*/)
{
}
tcp::socket socket_;
std::string message_;
};
class tcp_server
{
public:
tcp_server(boost::asio::io_service& io)
: acceptor_(io, tcp::endpoint(tcp::v4(),13))
{
start_accept();
}
private:
void start_accept()
{
//创建新tcp_connection对象,成员变量socket_将会作为acceptor的参数
tcp_connection::pointer new_connection =
tcp_connection::create(acceptor_.io_service());
//等待接受新连接
acceptor_.async_accept(new_connection->socket(),
boost::bind(&tcp_server::handle_accept,this,
new_connection,boost::asio::placeholders::error));
}
/*
*当async_accept接受新连接完成后呼叫handle_accept
*我们在这个函数中响应客户请求,并等待下个连接
*/
void handle_accept(tcp_connection::pointer new_connection,
boost::asio::error&error)
{
if(!error)
{
new_connection->start();
start_accept();
}
}
private:
/*
/// TCP socket 类型.
typedef basic_stream_socket<tcp> socket;
/// TCP acceptor 类型.
typedef basic_socket_acceptor<tcp> acceptor;
*/
tcp::acceptor acceptor_;
};
/*
io_service 类为异步i/o对象的用户提供核心 i/o功能(在windows2000以上环境使用完成端口)
如:
boost::asio::ip::tcp::socket
boost::asio::ip::tcp::acceptor
boost::asio::ip::udp::socket
boost::asio::deadline_timer
*/
int _tmain(int argc, _TCHAR* argv[])
{
try{
boost::asio::io_service io;
tcp_server server(io);
io.run();
}
catch(std::exception& e)
{
std::cerr << e.what() << std::endl;
}
return 0;
}
- Boost Asio
- boost asio
- Boost.asio
- boost asio
- boost asio
- boost.asio
- Boost.Asio
- boost.asio
- boost asio
- BOOST::ASIO
- boost asio
- boost asio
- boost asio
- Boost asio
- boost asio
- Boost asio.
- boost.asio
- [Boost.asio] boost asio 简单示例
- HDU4416(后缀自动机)
- 2012年——2013年总结
- 字符串 整形 连接
- 自定义控件-- 折线图--Android
- oracle随笔-Index (B*树索引-2)
- boost.asio
- [每日一题] 11gOCP 1z0-052 :2013-08-31 数据库的存储结构....................................................A8
- 回调设计模式
- openCV之cvSmooth高斯滤波器
- C++下遍历文件夹
- jsoup在jre6和jre7的不同表现
- Linux管道及重定向
- Codeforces Round #198 (Div. 2) C. Tourist Problem (数学+dp)
- CSDN的SDCC大会(2013)中使用的PPT分享