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

  1. 一篇文章看懂angularjs component组件

     壹 ❀ 引 我在 angularjs 一篇文章看懂自定义指令directive 一文中详细介绍了directive基本用法与完整属性介绍.directive是个很神奇的存在,你可以不设置templa ...

  2. 真的,Kafka 入门一篇文章就够了

    初识 Kafka 什么是 Kafka Kafka 是由 Linkedin 公司开发的,它是一个分布式的,支持多分区.多副本,基于 Zookeeper 的分布式消息流平台,它同时也是一款开源的基于发布订 ...

  3. Android:学习AIDL,这一篇文章就够了(下)

    前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...

  4. 使用Netty进行Android与Server端通信实现文字发送接收与图片上传

    ANOTHER TITLE: Let’s use netty to achieve text send and receive and  image transfer to server based ...

  5. 从缓冲上看阻塞与非阻塞socket在发送接收上的区别

    最近在网络上看到一些帖子以及回复,同时又搜索了一些网络上关于阻塞非阻塞区别的描述,发现很多人在描述两者的发送接收时操作返回以及缓冲区处理的区别时有不同程度的误解.所以我想写一篇文章来纠正错误,并作为记 ...

  6. (转载)Android:学习AIDL,这一篇文章就够了(下)

    前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...

  7. 一篇文章让你彻底弄懂SSL/TLS协议

    目录 SSL/TLS的应用 TLS协议的架构 握手协议 主密码和预备主密码 TLS记录协议 一篇文章让你彻底弄懂SSL/TLS协议 SSL/TLS是一种密码通信框架,他是世界上使用最广泛的密码通信方法 ...

  8. 还分不清 Cookie、Session、Token、JWT?一篇文章讲清楚

    还分不清 Cookie.Session.Token.JWT?一篇文章讲清楚 转载来源 公众号:前端加加 作者:秋天不落叶 什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证 ...

  9. UML科普文,一篇文章掌握14种UML图

    前言 上一篇文章写了一篇建造者模式,其中有几个UML类图,有的读者反馈看不懂了,我们今天就来解决一哈. 什么是UML? UML是Unified Model Language的缩写,中文是统一建模语言, ...

随机推荐

  1. OI——不后悔的两年

    NOI2014,悲惨的考跪,99+170+130 399 Cu滚粗.最终签到了复旦的一本,还算是有点结果吧.(其实我一开始就想读复旦我会说?)回首这两年,就像一场梦一样,从一无所知的小白到进入省队再到 ...

  2. 【转】linux之type命令

    转自: http://codingstandards.iteye.com/blog/831504 用途说明 type命令用来显示指定命令的类型.一个命令的类型可以是如下之一 alias 别名 keyw ...

  3. 【译】x86程序员手册20-6.3.4门描述符守卫程序入口

    6.3.4 Gate Descriptors Guard Procedure Entry Points 门描述符守卫程序入口 To provide protection for control tra ...

  4. Lazarus Coolbar and AnchroDocking

    在lazarus1.6里加载了AnchroDocking后,Coolbar突然不见了,找了好久没找到,原来在这里! 在AnchroDocking中可能是为了界面的最大化,默认是开始Toolbar 而关 ...

  5. img图片加载出错处理

    img图片加载出错处理   为了美观当网页图片不存在时不显示叉叉图片 当在页面显示的时候,万一图片被移动了位置或者丢失的话,将会在页面显示一个带X的图片,很是影响用户的体验.即使使用alt属性给出了” ...

  6. Python 之列表操作

    # len(list)列表元素个数 # max(list)返回列表元素最大值 # min(list)返回列表元素最小值 # list(seq)将元组转换为列表 # list.append(obj)在列 ...

  7. JS数组reduce()方法

    1.语法 arr.reduce(callback,[initialValue]) reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(或者上 ...

  8. CF1148D-Dirty Deeds Done Dirt Cheap

    这轮CF怎么充满了替身啊233(这是场只有替身使者才能看见的比赛) 题解可以看官方的 这里就是记录下自己当初是怎么没做上的233 忽视掉了分类后pair本身就会带有的性质(a<b or a> ...

  9. Java报表统计导出Word-xdocin方式

    官网:http://www.xdocin.com Controller层: //创建对象 XDocService xdocService = new XDocService(); //封装参数 Map ...

  10. web前端学习总结--JQuery

    jQuery 什么是jQuery jQuery是一个优秀的JavaScript框架,一个轻量级的JS库. 它封装了JS.CSS.DOM,提供了一致的.简洁的API. 兼容CSS3,及各种浏览器 使用户 ...