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. [转]asp.net MVC 常见安全问题及解决方案

    本文转自:http://www.cnblogs.com/Jessy/p/3539564.html asp.net MVC 常见安全问题及解决方案 一.CSRF (Cross-site request ...

  2. WinForms_ListView中获取选中项数据值

    string value = listList.SelectedItems[0].SubItems[1].Text;//获取首行listview的值 string va = listList.Sele ...

  3. mysql和java的时间对应关系

    引用:http://blog.csdn.net/xinghuo0007/article/details/51500923 MySQL(版本:5.1.50)的时间日期类型如下: datetime 8by ...

  4. ndk书写位置的问题

    defaultConfig { applicationId "com.chenql.helloandroidjni" minSdkVersion 22 targetSdkVersi ...

  5. Android基础TOP2_1:输出系统时间

    Activity: <TextView android:id="@+id/tv" android:layout_width="wrap_content" ...

  6. html——快捷键

    webstorm ctrl+c 复制 ctrl+v 粘贴 ctrl+x 剪切一行或删除一行 ctrl+d 复制本行到下一行 ctrl+z 退回之前操作 ctrl+shift+z 已经做好的退回之后的下 ...

  7. java攻城狮之路--复习xml&dom_pull编程

    xml&dom_pull编程: 1.去掉欢迎弹窗界面:在window项的preferences选项中输入“configuration center” 找到这一项然后     把复选框勾去即可. ...

  8. [Windows Server 2012] MySQL安全加固

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com ★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频. ★ 本节我们将带领大家:MySQL ...

  9. java实现搜索附近地点或人的功能

    前言 当前大多数app都有查找附近的功能, 简单的有查找周围的运动场馆, 复杂的有滴滴, 摩拜查找周围的车辆. 本文主要阐述查找附近地点的一般实现. 方案比较 方案1 (性能还不错) 数据库直接存经纬 ...

  10. Nginx+nagios安装配置

    Nginx+nagios安装配置 [root@Nagios ~]# vi /etc/nginx/nginx.conf server { listen ; server_name localhost; ...