Server
类包含的accept_connections()方法使用接受器(也就是ACE_SOCK_Acceptor)来将连接接受“进”ACE_SOCK_Stream new_stream_。该操作是这样来完成的:调用接受器上的accept(),并将流作为参数传入其中;我们想要接受器将连接接受进这个流。一旦连接已建立进流中,流的包装方法send()和recv()就可以用来在新建立的链路上发送和接收数据。还有一个空的ACE_INET_Addr也被传入接受器的accept()方法,并在其中被设定为发起连接的远地机器的地址。在连接建立后,服务器调用
handle_connection()方法,它开始从客户那里读取一个预先知道的单词,然后将流关闭。对于要处理多个客户的服务器来说,这也许并不是很实际的情况。在现实世界的情况中可能发生的是,连接在单独的线程或进程中被处理。在后续章节中将反复演示怎样完成这样的多线程和多进程类型的处理。连接关闭通过调用流上的
close()方法来完成,该方法会释放所有的socket资源并终止连接。下面的例子演示怎样与前面例子中演示的接受器协同使用连接器。
例
2-2#include "ace/SOCK_Connector.h"
#include "ace/INET_Addr.h"
#define SIZE_BUF 128
#define NO_ITERATIONS 5
class
Client{
public:
Client
(char *hostname, int port):remote_addr_(port,hostname){
data_buf_="Hello from Client";
}
//Uses a connector component `connector_’ to connect to a
//remote machine and pass the connection into a stream
//component client_stream_
int
connect_to_server(){
// Initiate blocking connection with server.
ACE_DEBUG ((LM_DEBUG, "(%P|%t) Starting connect to %s:%d\n",
remote_addr_.get_host_name(),remote_addr_.get_port_number()));
if (connector_.connect (client_stream_, remote_addr_) == -1)
ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","connection failed"),-1);
else
ACE_DEBUG ((LM_DEBUG,"(%P|%t) connected to %s\n",
remote_addr_.get_host_name ()));
return 0;
}
//Uses a stream component to send data to the remote host.
int
send_to_server(){
// Send data to server
for(int i=0;i
{
if (client_stream_.send_n (data_buf_,
ACE_OS::strlen(data_buf_)+1, 0) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","send_n"),0);
break;
}
}
//Close down the connection
close();
}
//Close down the connection properly.
int
close(){
if (client_stream_.close () == -1)
ACE_ERROR_RETURN ((LM_ERROR,"(%P|%t) %p\n","close"),-1);
else
return 0;
}
private:
ACE_SOCK_Stream client_stream_;
ACE_INET_Addr remote_addr_;
ACE_SOCK_Connector connector_;
char *data_buf_;
};
int
main (int argc, char *argv[]){
if(argc<3)
{
ACE_DEBUG((LM_DEBUG,”Usage %s
\n”, argv[0])); ACE_OS::exit(1);
}
Client client(argv[1],ACE_OS::atoi(argv[2]));
client.connect_to_server();
client.send_to_server();
}
上面的例子演示的客户主动连接到例
2-1所描述的服务器。在建立连接后,客户将单个字符串发送若干次到服务器,并关闭连接。客户由单个
Client类表示。Client含有connect_to_server()和send_to_server()方法。Connect_to_server()
方法使用类型为ACE_SOCK_Connector的连接器(connector_)来主动地建立连接。连接的设置通过调用连接器connector_上的connect()方法来完成:传入的参数为我们想要连接的机器的地址remote_addr_,以及用于在其中建立连接的空ACE_SOCK_Stream client_stream_。远地机器在例子的运行时参数中指定。一旦connect()方法成功返回,通过使用ACE_SOCK_Stream封装类中的send()和recv()方法族,流就可以用于在新建立的链路上发送和接收数据了。在此例中,一旦连接建立好,
send_to_server()方法就会被调用,以将一个字符串发送NO_ITERATIONS次到服务器。如前面所提到的,这是通过使用流包装类的send()方法来完成的。
