一篇文章贯穿ACE各种发送接收组件 1.2版
TCP通信过程介绍
首先介绍一下socket通信的基本过程:这里先如果有两个家伙在通信,一个是S。还有一个叫C
(1)S打开port监听本地的port看看有没有人来连接;
(2)与此同一时候C试图去连接远程的S。连接的地址就是S的地址加上S监听的port号;
(3)S收到C的请求之后,建立连接,两方共同持有连接的通道。可互相发送/接收数据随意次。此时S和C无差别。
(4)当中一方断开连接,或者由于网络原因中断连接,还有一方也会关闭;
(5)此时通信过程结束;
整个步骤例如以下图所看到的
普通ACE通信类ACE_SOCK_*通信过程
ACE_SOCK_Connector ACE_SOCK_Stream ACE_SOCK_Acceptor完毕上面的通信过程:
TimerServer Edition 1.0 单次发送
两方建立连接》互发数据》关闭连接
Client:发送自己的签名给Server之后就准备接受Server发来的时间
Server:在连接建立后打印对方发来的签名。之后回复自己的时间给对方
Server 端 time_server_main.cpp
#include <ace/OS.h>
#include <ace/ACE.h>
#include <ace/Log_Msg.h>
#include <ace/SOCK_Acceptor.h>
#include "ace/Date_Time.h" int main(int argc, char *argv[])
{
ACE_INET_Addr addr(1500);
ACE_SOCK_Acceptor server;
ACE_SOCK_Stream stream; //启动监听
if(server.open(addr)==-1)
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500失败\n")));
return 1;
}
else
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500成功\n")));
} char msg[1000]; //建立链接
if(server.accept(stream)!=-1)
{
ACE_INET_Addr raddr;
stream.get_remote_addr(raddr);
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接成功 %s %d\n"),raddr.get_host_addr(),raddr.get_port_number())); if(stream.recv(msg,sizeof(msg)-1)==-1) // just call socket recv
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server recv failed\n")));
else
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server recv : %s\n"),msg));
//get current time
ACE_Date_Time date;
sprintf(msg,"%ld-%ld-%ld %02ld:%02ld:%02ld:%02ld",date.year(),date.month(),date.day(),date.hour(),date.minute(),date.second(),date.microsec());
//发送数据
stream.send_n(msg,sizeof(msg));
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("发送当前时间%s至 %s %d\n"),msg,raddr.get_host_addr(),raddr.get_port_number()));
}
}
else
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接失败\n")));
}
//关闭链接
stream.close();
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server链接关闭了\n")));
server.close(); return 0;
}
Client端time_client_main.cpp
#include "ace/OS.h"
#include <ace/OS_main.h>
#include <ace/ACE.h>
#include <ace/Log_Msg.h>
#include <ace/SOCK_Connector.h> int main(int argc, char *argv[])
{
ACE_INET_Addr addr(1500,"127.0.0.1"); //remote address
ACE_SOCK_Connector con; // connetor for socket client
ACE_SOCK_Stream stream; // stream is for socket read/write //建立链接
if(con.connect(stream,addr)==-1) //connect to remote address
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接失败\n")));
return 1;
}
else
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接成功\n")));
} const char msg[] = "Hello,ACE!";
//发送数据
stream.send_n(msg,sizeof(msg)); // send_n function send exactly n bytes char buffer[1024] = {0};
//接收数据
if(stream.recv(buffer,sizeof(buffer)-1)==-1) // just call socket recv
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv failed\n")));
return 1;
}
else
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv:%s\n"),buffer));
} //断开链接
if (stream.close () == -1) //close the connection
{
ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close failed\n")));
return 1;
}
else
{
ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close successed\n")));
}
return 0;
}
输出:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2FsbXJlYXNvbg==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
TimerServer Edition 2.0 多次发送
两方建立连接》互发数据》关闭连接
(1)Client:发送自己的签名给Server之后就准备接受Server发来的时间,此过程反复三次
(2)Server:在连接建立后打印对方发来的签名。之后回复自己的时间给对方。此过程直到对方关闭链接
Server 端 time_server_main.cpp
#include <ace/OS.h>
#include <ace/ACE.h>
#include <ace/Log_Msg.h>
#include <ace/SOCK_Acceptor.h>
#include "ace/Date_Time.h" int main(int argc, char *argv[])
{
ACE_INET_Addr addr(1500);
ACE_SOCK_Acceptor server;
ACE_SOCK_Stream stream; //启动监听
if(server.open(addr)==-1)
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500失败\n")));
return 1;
}
else
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500成功\n")));
} char msg[1000]; //建立链接
if(server.accept(stream)!=-1)
{
ACE_INET_Addr raddr;
stream.get_remote_addr(raddr);
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接成功 %s %d\n"),raddr.get_host_addr(),raddr.get_port_number())); while(stream.recv(msg,sizeof(msg)-1)!=-1) // just call socket recv
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server recv : %s\n"),msg));
//get current time
ACE_Date_Time date;
sprintf(msg,"%ld-%ld-%ld %02ld:%02ld:%02ld:%02ld",date.year(),date.month(),date.day(),date.hour(),date.minute(),date.second(),date.microsec());
//发送数据
stream.send_n(msg,sizeof(msg));
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("发送当前时间%s至 %s %d\n"),msg,raddr.get_host_addr(),raddr.get_port_number()));
ACE_OS::sleep(1);
}
}
else
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接失败\n")));
}
//关闭链接
stream.close();
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server链接关闭了\n")));
server.close(); return 0;
}
Client端time_client_main.cpp
#include "ace/OS.h"
#include <ace/OS_main.h>
#include <ace/ACE.h>
#include <ace/Log_Msg.h>
#include <ace/SOCK_Connector.h> int main(int argc, char *argv[])
{
ACE_INET_Addr addr(1500,"127.0.0.1"); //remote address
ACE_SOCK_Connector con; // connetor for socket client
ACE_SOCK_Stream stream; // stream is for socket read/write //建立链接
if(con.connect(stream,addr)==-1) //connect to remote address
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接失败\n")));
return 1;
}
else
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接成功\n")));
} const char msg[] = "I'm Client ABC";
//发送数据
int n=3;
for (int i=0; stream.send_n(msg,sizeof(msg)) != -1 && i<3;++i)
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client send successed\n"))); char buffer[1024] = {0};
//接收数据
if(stream.recv(buffer,sizeof(buffer)-1)==-1) // just call socket recv
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv failed\n")));
return 1;
}
else
{
ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv:%s\n"),buffer));
}
ACE_OS::sleep(1);
} //断开链接
if (stream.close () == -1) //close the connection
{
ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close failed\n")));
return 1;
}
else
{
ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close successed\n")));
}
return 0;
}
TimerServer Edition 2.0 多次发送
多个client分多次发送
一篇文章贯穿ACE各种发送接收组件 1.2版的更多相关文章
- 一篇文章看懂angularjs component组件
壹 ❀ 引 我在 angularjs 一篇文章看懂自定义指令directive 一文中详细介绍了directive基本用法与完整属性介绍.directive是个很神奇的存在,你可以不设置templa ...
- 真的,Kafka 入门一篇文章就够了
初识 Kafka 什么是 Kafka Kafka 是由 Linkedin 公司开发的,它是一个分布式的,支持多分区.多副本,基于 Zookeeper 的分布式消息流平台,它同时也是一款开源的基于发布订 ...
- Android:学习AIDL,这一篇文章就够了(下)
前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...
- 使用Netty进行Android与Server端通信实现文字发送接收与图片上传
ANOTHER TITLE: Let’s use netty to achieve text send and receive and image transfer to server based ...
- 从缓冲上看阻塞与非阻塞socket在发送接收上的区别
最近在网络上看到一些帖子以及回复,同时又搜索了一些网络上关于阻塞非阻塞区别的描述,发现很多人在描述两者的发送接收时操作返回以及缓冲区处理的区别时有不同程度的误解.所以我想写一篇文章来纠正错误,并作为记 ...
- (转载)Android:学习AIDL,这一篇文章就够了(下)
前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...
- 一篇文章让你彻底弄懂SSL/TLS协议
目录 SSL/TLS的应用 TLS协议的架构 握手协议 主密码和预备主密码 TLS记录协议 一篇文章让你彻底弄懂SSL/TLS协议 SSL/TLS是一种密码通信框架,他是世界上使用最广泛的密码通信方法 ...
- 还分不清 Cookie、Session、Token、JWT?一篇文章讲清楚
还分不清 Cookie.Session.Token.JWT?一篇文章讲清楚 转载来源 公众号:前端加加 作者:秋天不落叶 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证 ...
- UML科普文,一篇文章掌握14种UML图
前言 上一篇文章写了一篇建造者模式,其中有几个UML类图,有的读者反馈看不懂了,我们今天就来解决一哈. 什么是UML? UML是Unified Model Language的缩写,中文是统一建模语言, ...
随机推荐
- query.setFirstResult(0),query.setMaxResults(4)
query.setFirstResult(0),query.setMaxResults(1);相当于MySQL中的limit 0, 1; String hql = "FROM Forum f ...
- Java中static方法
今天学习到了并且应用到了java中的静态方法,并且了解到它的好处与缺点. ● 生命周期(Lifecycle): 静态方法(Static Method)与静态成员变量一样,属于类本身,在类装载的时候被装 ...
- Android RecyclerView使用 及 滑动时加载图片优化方案
1.控制线程数量 + 数据分页加载2.重写onScrollStateChanged方法 这个我们后面再谈,下面先来看看RecyclerView控件的使用及我们为什么选择使用它 RecyclerView ...
- 前端开发之旅-zopim在线即时聊天客服
一.与潜在客户实时聊天的神奇-zopim Zopim是一款高效的可嵌入网页中去的即使通讯与网站访客信息追踪的的Web软件.知道谁在访问您的网站吗?想和他们实时交流吗?想更有效的把握商机吗?使用Zopi ...
- Android集成二维码扫描功能
文章转载自 https://github.com/yipianfengye/android-zxingLibrary 在具体介绍该扫描库之前我们先看一下其具体的使用方式,看看是不是几行代码就可以集成 ...
- ffmpeg rtp时间戳
ffmpeg rtp时间戳 ffmpeg c 一.介绍 在ffmpeg中,每帧都会存在一个pts用来表示该帧图像在视频流中的位置.而在多路流(比如视频.音频)时,往往需要进行多媒体的同步,使得画面 ...
- Angular——todos案例
基本介绍 (1)视图绑定两个数组,分别对应未完成和已完成 (2)数组的删除splice(),数组的追加push() 基本使用 <!DOCTYPE html> <html lang=& ...
- CSS动画:旋转卡片效果
<!DOCTYPE html> <html> <head> <title>demo</title> </head> <bo ...
- Nginx+nagios安装配置
Nginx+nagios安装配置 [root@Nagios ~]# vi /etc/nginx/nginx.conf server { listen ; server_name localhost; ...
- nodejs 文件操作模块 fs
const fs=require("fs"); //文件操作 //创建目录 ./ 代表当前目录 ../ 代表上级目录fs.mkdir('./test',function(err){ ...