一篇文章贯穿ACE各种发送接收组件 1.2版

本文深入探讨了TCP通信的基本过程,并通过实例展示了ACE通信类和TimerServerEdition的使用方法,详细介绍了通信双方如何建立连接、互发数据及关闭连接的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TCP通信过程介绍

    首先介绍一下socket通信的基本过程:这里先假设有两个家伙在通信,一个是S,另一个叫C

(1)S打开端口监听本地的端口看看有没有人来连接;

(2)与此同时C试图去连接远程的S,连接的地址就是S的地址加上S监听的端口号;

(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;
}


输出:


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  多次发送

多个客户端分多次发送





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

C++程序员Carea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值