zoukankan      html  css  js  c++  java
  • 一篇文章贯穿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失败
    ")));
            return 1;
        }
        else
        {
            ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500成功
    ")));
        }
    
        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
    "),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
    ")));
            else
            {
                ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server recv : %s
    "),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
    "),msg,raddr.get_host_addr(),raddr.get_port_number()));
            }
        }
        else
        {
            ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接失败
    ")));
        }
        //关闭链接
        stream.close();
        ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server链接关闭了
    ")));
        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建立链接失败
    ")));
            return 1;
        }
        else
        {
            ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接成功
    ")));
        }
    
        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
    ")));
            return 1;
        }
        else
        {
            ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv:%s
    "),buffer));
        }
            
        //断开链接
        if (stream.close () == -1) //close the connection
        {
            ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close failed
    ")));
            return 1;
        }
        else
        {
            ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close successed
    ")));
        }
        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失败
    ")));
            return 1;
        }
        else
        {
            ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server启动监听本地端口1500成功
    ")));
        }
    
        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
    "),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
    "),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
    "),msg,raddr.get_host_addr(),raddr.get_port_number()));
                ACE_OS::sleep(1);
            }
        }
        else
        {
            ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server建立链接失败
    ")));
        }
        //关闭链接
        stream.close();
        ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Server链接关闭了
    ")));
        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建立链接失败
    ")));
            return 1;
        }
        else
        {
            ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client建立链接成功
    ")));
        }
    
        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
    ")));
    
            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
    ")));
                return 1;
            }
            else
            {
                ACE_DEBUG ((LM_DEBUG,ACE_TEXT ("Client recv:%s
    "),buffer));
            }
            ACE_OS::sleep(1);
        }
    
        //断开链接
        if (stream.close () == -1) //close the connection
        {
            ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close failed
    ")));
            return 1;
        }
        else
        {
            ACE_ERROR ((LM_ERROR,ACE_TEXT ("Client close successed
    ")));
        }
        return 0;
    }
    



    TimerServer Edition 2.0  多次发送

    多个client分多次发送





  • 相关阅读:
    【设计模式】适配器模式
    【设计模式】原型模式
    【设计模式】建造者模式
    【设计模式】抽象工厂模式
    我的稳定的SpingBoot项目依赖
    Vue中使用iconfont
    Vue-兄弟组件传值
    CSS让高度百分百的方案
    css修改overflow滚动条默认样式
    CSS去除input和textarea点击选中框
  • 原文地址:https://www.cnblogs.com/mthoutai/p/6915819.html
Copyright © 2011-2022 走看看