1. 程式人生 > >一篇文章貫穿ACE各種發送接收組件 1.2版

一篇文章貫穿ACE各種發送接收組件 1.2版

font 多次 ++ 兩個 sock tor 當前 int cto

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


輸出:

技術分享

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版