您的位置:首页 > 理论基础 > 计算机网络

ACE网络库的UDP通信(数据报)的使用

2016-05-25 21:27 423 查看
使用ACE的数据报
        ACE_SOCK_Dgram和ACE_LSOCK_Dgram是ACE中的数据报包装类。这些包装包含了发送和接收数据报的方法,并包装了非面向连接的UDP协议和UNIX域socket协议。与流包装不同,这些包装封装的是非面向连接的协议。这也就意味着不存在用于“设置”连接的接受器和连接器。相反,在这种情况下,通信通过一系列的发送和接收来完成。每个send()都要指定目的远地地址作为参数。下面的例子演示怎样通过ACE使用数据报。这个例子使用了ACE_SOCK_Dgram包装(也就是UDP包装)。还可以使用包装UNIX域数据报的ACE_LSOCK_Dgram。两种包装的用法非常类似,唯一的不同是ACE_LSOCK_Dgram要用ACE_UNIX_Addr类作为地址,而不是ACE_INET_Addr。

#pragma once
//例2 - 3
//Server
#include "stdafx.h"
#include "ace/Log_Msg.h"
#include "ace/OS.h"
#include "ace/SOCK_Dgram.h"
#include "ace/INET_Addr.h"

#define DATA_BUFFER_SIZE 1024
#define SIZE_DATA 19

class Server
{
public:
Server(int local_port)
:local_addr_(local_port), local_(local_addr_)
{
data_buf = new char[DATA_BUFFER_SIZE];
}
//Expect data to arrive from the remote machine. Accept it and display
//it. After receiving data, immediately send some data back to the
//remote.
int accept_data()
{
int byte_count = 0;
while ((byte_count = local_.recv(data_buf, SIZE_DATA, remote_addr_)) != -1)
{
data_buf[byte_count] = 0;
ACE_DEBUG((LM_DEBUG, "Data received from remote %s was %s /n"
, remote_addr_.get_host_name(), data_buf));
ACE_OS::sleep(1);
if (send_data() == -1) break;
}
return -1;
}
//Method used to send data to the remote using the datagram component
//local_
int send_data()
{
ACE_DEBUG((LM_DEBUG, "Preparing to send reply to client %s:%d/n",
remote_addr_.get_host_name(), remote_addr_.get_port_number()));
ACE_OS::sprintf(data_buf, "Server says hello to you too");
if (local_.send(data_buf, ACE_OS::strlen(data_buf) + 1, remote_addr_) == -1)
return -1;
else
return 0;
}
private:
char *data_buf;
ACE_INET_Addr remote_addr_;
ACE_INET_Addr local_addr_;
ACE_SOCK_Dgram local_;
};

int main(int argc, char *argv[])
{
if (argc < 2)
{
ACE_DEBUG((LM_DEBUG, "Usage %s <Port Number>", argv[0]));
ACE_OS::exit(1);
}
Server server(ACE_OS::atoi(argv[1]));
server.accept_data();
return 0;
}


        上面的代码是一个简单的服务器,它等待客户应用通过已知端口给它发送一个数据报。在该数据报中含有定长的和预定数量的数据。服务器在收到这些数据时,就发送回复给原先发送数据的客户。

Server类拥有名为local_的ACE_SOCK_Dgram私有成员,它被同时用于接收和发送数据。Server在它的构造器中通过已知的ACE_INET_Addr(本地主机以及已知端口)实例化local_,这样客户就可以对它进行定位、并发送消息给它了。

        Server主函数实例化相应的客户代码与前面的服务器例子非常类似:

类包含两个方法:accept_data(),用于从客户接收数据(使用recv()调用包装);以及send_data(),用于发送数据给远地客户(使用send()调用包装)。注意local_包装类的send()和receive()的底层调用都包装了BSD sendto()和recvfrom()调用,并具有相类似的特征。Server类型的对象、并调用它的accept_data()方法,等待来自客户的数据。当它得到所需的数据后,它调用send_data()发送回复消息给客户。如此循环往复,直到客户被关闭为止。

相应的客户端代码与前面的服务端代码非常相似:

//例2 - 4
//Client
// ACE_Dgram_Client.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include "ace/Log_Msg.h"
#include "ace/OS.h"
#include "ace/SOCK_Dgram.h"
#include "ace/INET_Addr.h"

#define DATA_BUFFER_SIZE 1024
#define SIZE_DATA 28

class Client
{
public:
Client(char * remote_host, int port)
:remote_addr_(remote_host),
local_addr_((u_short)0), local_(local_addr_)
{
data_buf = new char[DATA_BUFFER_SIZE];
remote_addr_.set_port_number(port);
}
//Receive data from the remote host using the datgram wrapper `local_’.
//The address of the remote machine is received in `remote_addr_’
//which is of type ACE_INET_Addr. Remember that there is no established
//connection.
int accept_data()
{
if (local_.recv(data_buf, SIZE_DATA, remote_addr_) != -1)
{
ACE_DEBUG((LM_DEBUG, "Data received from remote server %s was: %s /n",
remote_addr_.get_host_name(), data_buf));
return 0;
}
else
return -1;
}
//Send data to the remote. Once data has been sent wait for a reply
//from the server.
int send_data()
{
ACE_DEBUG((LM_DEBUG, "Preparing to send data to server %s:%d/n",
remote_addr_.get_host_name(), remote_addr_.get_port_number()));
ACE_OS::sprintf(data_buf, "Client says hello");
while (local_.send(data_buf, ACE_OS::strlen(data_buf), remote_addr_) != -1)
{
ACE_OS::sleep(1);
if (accept_data() == -1)
break;
}
return -1;
}
private:
char *data_buf;
ACE_INET_Addr remote_addr_;
ACE_INET_Addr local_addr_;
ACE_SOCK_Dgram local_;
};

int main(int argc, char *argv[])
{
if (argc < 3)
{
ACE_OS::printf("Usage: %s <hostname> <port_number> /n", argv[0]);
ACE_OS::exit(1);
}
Client client(argv[1], ACE_OS::atoi(argv[2]));
client.send_data();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: