网络通信简述

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处理的更多相关文章

  1. [Boost基础]并发编程——asio网络库——异步socket处理

    异步服务器端 #include <conio.h> #include <iostream> using namespace std; #include <boost/as ...

  2. [Boost基础]并发编程——asio网络库——定时器deadline_timer

    asio库基于操作系统提供的异步机制,采用前摄器设计模式(Proactor)实现了可移植的异步(或者同步)IO操作,而且并不要求使用多线程和锁定,有些的避免了多线程编程带来的诸多有害副作用(如条件竞争 ...

  3. Java并发编程的4个同步辅助类

    Java并发编程的4个同步辅助类(CountDownLatch.CyclicBarrier.Semphore.Phaser) @https://www.cnblogs.com/lizhangyong/ ...

  4. Java并发编程:线程的同步

    Java并发编程:线程的同步 */--> code {color: #FF0000} pre.src {background-color: #002b36; color: #839496;} J ...

  5. Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semaphore、Phaser)

    我在<JDK1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...

  6. Java并发编程的4个同步辅助类(CountDownLatch、CyclicBarrier、Semphore、Phaser)

    我在<jdk1.5引入的concurrent包>中,曾经介绍过CountDownLatch.CyclicBarrier两个类,还给出了CountDownLatch的演示案例.这里再系统总结 ...

  7. python基础-并发编程02

    并发编程 子进程回收的两种方式 join()让主进程等待子进程结束,并回收子进程资源,主进程再结束并回收资源 from multiprocessing import Process import ti ...

  8. python语法基础-并发编程-进程-进程理论和进程的开启

    ############################################## """ 并发编程的相关概念: 进程 1,运行中的程序,就是进程,程序是没有生 ...

  9. 跨平台高效率Lua网络库 ( 同步形式的API ,底层是异步非阻塞)

    Joynet 项目地址:https://github.com/IronsDu/Joynet 介绍 high performance network library for lua, based on  ...

随机推荐

  1. 三个C++资源链接(大量)

    https://github.com/fffaraz/awesome-cpp http://blog.jobbole.com/78901/ https://github.com/programthin ...

  2. 基于visual Studio2013解决C语言竞赛题之0301函数求值

     题目 解决代码及点评 #include <stdio.h> #include <stdlib.h> #include <math.h> void main() ...

  3. linux grep详解

    Table of Contents 1. grep简介 2. grep正则表达式元字符集(基本集) 3. 用于egrep和 grep -E的元字符扩展集 4. POSIX字符类 5. Grep命令选项 ...

  4. Python类的继承演示样例

    class Pet: __name = "" def __init__(self, name): self.__name = name def bark(self): return ...

  5. BZOJ 3403: [Usaco2009 Open]Cow Line 直线上的牛( deque )

    直接用STL的的deque就好了... ---------------------------------------------------------------------- #include& ...

  6. Tomcat 常规配置并通过zabbix 监控 jvm状态

    一:jdk和tomcat基础 apache有两种方式运行php,一是使用模块,二是使用fastcgi nginx也可以通过fastcgi处理动态请求,也可以转发至tomcat tomcat监控主要是监 ...

  7. modelsim中的文件操作—— 大数据测试

    在modelsim中不可避免的需要进行文件操作,在窗口中查看代码的操作情况,下面是我自己M序列实验中的一段测试代码 integer i,j ,k,m; integer m_dataFILE , ind ...

  8. ajax请求响应中用window.open打开新窗口会被浏览器拦截的解决方式

    一.问题描述 ajax 异步请求成功后需要新开窗口打开 url,使用的是 window.open() 方法,但是会被浏览器给拦截了,需要用户点下. 二.问题分析 浏览器之所以拦截新开窗口是因为该操作并 ...

  9. 17.1 Replication Configuration

    17.1 Replication Configuration 17.1.1 How to Set Up Replication 17.1.2 Replication Formats 17.1.3 Re ...

  10. Android平台下使用lua调用Java代码经验总结

    动态语言以其执行的灵活性,可配置性.方便调试能够为开发带来极大的方便.假设用好了.能够极大的提高开发的效率. 怪不得像游戏开发这样复杂的软件开发里没有不集成脚本语言的. 当中,lua以其小巧,灵活.方 ...