[Boost基础]并发编程——asio网络库——同步socket处理
网络通信简述
asio库支持TCP,UDP和ICMP通信协议,它在名字空间boost::asio::ip里提供了大量的网络通信方面的函数和类,很好的封装了原始的Berkeley Socket API,展现给asio用户一个方便易用且健壮的网络通信库。
ip::tcp类是asio网络通信(TCP)部分主要的类,但它本身并没有太多的功能,而且定义了数个用于TCP通信的typedef类型,用来协作往常网络通信。这些typedef包括端点类endpoint,套接字类socket,流类iostream,以及接收器acceptor,解析器resolver等等。从某种程度上来看,ip::tcp类更像是一个名字空间。
ip::tcp的内部类型socket,acceptor和resolver是asio库TCP通信中最核心的一组类,他们封装了socket的连接 ,断开和数据收发功能,使用他们可以很容易的编写出socket程序。
- socket类是TCP通信的基本类,调用成员函数connect()可以连接到一个指定的通信端点,连接成功后用local_endpoint()和remote_endpoint()获得连接两端的端点信息,用read_some和write_some阻塞读写数据,当操作往常后使用close()函数关闭socket.如果不关闭socket,那么socket对象析构是也会自动调用close()关闭。
- acceptor类对于的socket API的accept()函数功能,他用于服务器端,在指定的端口号接受连接,必须配合socket类才能完成通信。
- resolver类对应socket API的getaddrinfo系列函数,用于客户端解析网址获得可用的IP地址,解析得到的IP地址可用使用socket对象连接。
同步服务器端
#include <conio.h>
#include <iostream>
using namespace std;
#include <boost/asio.hpp>
using namespace boost;
using namespace boost::asio;
//同步server----它用一个acceptor对象在6688端口接受连接,当有连接是使用一socket对象发送一个字符串
void test1()
{
try
{
io_service ios;
ip::tcp::acceptor acceptor(ios,ip::tcp::endpoint(ip::tcp::v4(),6688));
cout<<acceptor.local_endpoint().address()<<endl;
while(true)
{
ip::tcp::socket sock(ios);
acceptor.accept(sock);//阻塞等待socket连接
cout<<"client:ip:"<<sock.remote_endpoint().address()<<" port:"<<sock.remote_endpoint().port()<<endl;
sock.write_some(buffer("hello asio"));
//服务器端程序里要注意的是自由函数buffer(),它可用包装很多种类的容器成为asio组件可用的缓冲区类型。通常我们不能直接把数组,vector等容器用作asio的读写参数,必须使用buffer()函数包装。
}
}
catch(std::exception& e)
{
cout<<e.what()<<endl;
}
}
void test2()
{
}
void test3()
{ }
void test(char t)
{
std::cout<<"press key====="<<t<<std::endl;
switch (t)
{
case '1':test1();break;
case '2':test2();break;
case '3':test3();break;
case 27:
case 'q':exit(0);break;
default: std::cout<<"default "<<t<<std::endl;break;
}
}
void main()
{
while (1)
{
test(getch());
}
}
同步客户端
#include <conio.h>
#include <iostream>
using namespace std;
#include <boost/asio.hpp>
#include <boost/bind.hpp>
using namespace boost;
using namespace boost::asio; //IP地址和端点
//IP地址独立于TCP,UDP等通信协议,asio库使用类ip::address来表示IP地址,可以同时支持ipv4和ipv6两种地址。
void test1()
{
ip::address addr=addr.from_string("127.0.0.1");
assert(addr.is_v4());
cout<<addr.to_string()<<endl;
addr=addr.from_string("ab::12:34:56");
assert(addr.is_v6());
//有了ip地址,再加上通信用的端口就构成了一个socket端点,在asio库中用ip::tcp::endpoint类来表示。
ip::address addr1=addr1.from_string("127.0.0.1");
ip::tcp::endpoint ep(addr1,6688);//创建一个端点对象,端口为6688
assert(ep.address()==addr1);
assert(ep.port()==6688);
}
//同步socket处理
class a_timer
{
private:
int count,cout_max; //计数器成员变量
function<void()> f; //function对象,持有无参数无返回的可调用物
deadline_timer t;//asio定时器
public:
//构造函数初始化成员变量,将计数器清理,设置计数器的上限,拷贝存储回调函数,并立即启动定时器
//之所以要"立即"启动,是因为我们必须包装在io_service.run()之前至少有一个异步操作在执行,否则io_service.run()会因为没有事件处理而立即不等待返回。
template<typename F>a_timer(io_service& ios,int x,F func):f(func),cout_max(x),count(0),t(ios,posix_time::microsec(500))//模板类型,可接受任意可调用物
{
t.async_wait(bind(&a_timer::call_func,this,placeholders::error));//命名空间下asio::placeholders的一个占位符error,他的作用类似于bind库的占位符_1,_2,用于传递errror_code值。
} //call_func()内部累加计数器,如果计数器未达到上限则调用function对象f,然后重新设置定时器的终止时间,再次异步等待被调用,从而达到反复执行的目的。
void call_func(const boost::system::error_code &)
{
if(count >= cout_max)
{
return;
}
++count;
f();
t.expires_at(t.expires_at()+posix_time::millisec(500));//设置定时器的终止时间为0.5秒之后
t.async_wait(bind(&a_timer::call_func,this,placeholders::error));
}
};
void client(io_service& ios)
{
try
{
cout<<"client start."<<endl;
ip::tcp::socket sock(ios);
ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"),6688);//创建连接端点
sock.connect(ep);//socket连接到端点
vector<char> str(100,0);//定义一个vector缓冲区
sock.read_some(buffer(str));//使用buffer()包装缓冲区接收数据
cout<<"recive from: ip:"<<sock.remote_endpoint().address()<<" port:"<<sock.remote_endpoint().port()<<endl;
cout<<"recv:"<<&str[0]<<endl;//输出接收到的数据
}
catch(std::exception& e)
{
cout<<e.what()<<endl;
}
}
//同步客户端
void test2()
{
io_service ios;
a_timer at(ios,5,bind(client,ref(ios)));
ios.run();
}
void test3()
{
}
void test(char t)
{
std::cout<<"press key====="<<t<<std::endl;
switch (t)
{
case '1':test1();break;
case '2':test2();break;
case '3':test3();break;
case 27:
case 'q':exit(0);break;
default: std::cout<<"default "<<t<<std::endl;break;
}
}
void main()
{
while(1)
test(getch());
}
[Boost基础]并发编程——asio网络库——同步socket处理的更多相关文章
- [Boost基础]并发编程——asio网络库——异步socket处理
异步服务器端 #include <conio.h> #include <iostream> using namespace std; #include <boost/as ...
- [Boost基础]并发编程——asio网络库——定时器deadline_timer
asio库基于操作系统提供的异步机制,采用前摄器设计模式(Proactor)实现了可移植的异步(或者同步)IO操作,而且并不要求使用多线程和锁定,有些的避免了多线程编程带来的诸多有害副作用(如条件竞争 ...
- Java并发编程的4个同步辅助类
Java并发编程的4个同步辅助类(CountDownLatch.CyclicBarrier.Semphore.Phaser) @https://www.cnblogs.com/lizhangyong/ ...
- Java并发编程:线程的同步
Java并发编程:线程的同步 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: #839496;} J ...
- Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)
我在<JDK1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...
- Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semphore、Phaser)
我在<jdk1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...
- python基础-并发编程02
并发编程 子进程回收的两种方式 join()让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源 from multiprocessing import Process import ti ...
- python语法基础-并发编程-进程-进程理论和进程的开启
############################################## """ 并发编程的相关概念: 进程 1,运行中的程序,就是进程,程序是没有生 ...
- 跨平台高效率Lua网络库 ( 同步形式的API ,底层是异步非阻塞)
Joynet 项目地址:https://github.com/IronsDu/Joynet 介绍 high performance network library for lua, based on ...
随机推荐
- 顺为资本CEO许达来:为什么说中国创业者很幸福?(附PPT)
顺为资本创始合伙人许达来 编者按:许达来,顺为资本创始合伙人及CEO,代表性投资项目包括小米科技.丁香园.一起作业.加一联创.金山软件及兴达国际等. 本文为许达来在新浪创业举办的新创课活动上的内容分享 ...
- 看看微软代码的水平——Windows Live Writer 完成开源并推出开源分支
http://www.oschina.net/news/68860/windows-live-writer-opensource
- 谷歌三大核心技术(一)The Google File System中文版
谷歌三大核心技术(一)The Google File System中文版 The Google File System中文版 译者:alex 摘要 我们设计并实现了Google GFS文件系统,一个 ...
- Niagara技术文档汇总
Niagara技术文档汇总http://wenku.baidu.com/view/ccdd4e2c3169a4517723a38f.html Niagara讲解要点http://wenku.baidu ...
- BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路
1726: [Usaco2006 Nov]Roadblocks第二短路 Description 贝茜把家搬到了一个小农场,但她常常回到FJ的农场去拜访她的朋友.贝茜很喜欢路边的风景,不想那么快地结束她 ...
- Unix/Linux环境C编程新手教程(5) Red Hat Enterprise Linux(RHEL)环境搭建
Unix/Linux版本号众多,我们推荐Unix/Linux刚開始学习的人选用几款典型的Unix/Linux操作系统进行学习. 通过./a.out ./Y.out运行出结果,证明C++程序编译成功.也 ...
- Servlet中通过过滤器实现统一的手动编码(解决中文乱码)
1.web.xml片段: <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi= ...
- Chapter 13 建造者模式
建造者模式又叫生成器模式:将一个产品的内部表象与产品的生成过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象. 代码: package xiao; import java.util. ...
- 部署ASP.NET MVC项目
目标:了解部署过程,掌握部署中出现问题该如何处理. 部署网站往往是一件麻烦事,因为在安装部署的过程中,经常有许多步骤要运行,对于许多不太熟悉IIS/SQL的新手来说,部署网站编程一件非常困难且危险的事 ...
- docker学习笔记7:发布镜像到docker hub上
镜像创建好后,很重要的一个操作就是共享和发布.可以将自己创建的镜像发布到docker hub上,也可以发布到自己的私有docker hub上. 要想发布镜像到dokcer hub上,首先要在dokce ...