ACE之(二)ACE Socket封装器

2 ACE Socket封装器

这部分内容不是ACE的网络框架,而是ACE对Socket API的面向对象的封装,在ACE中称为Socket Wrapper Facade。它是ACE网络框架的基础。

ACE将Socket应用接口封装到3个不同的类中,它们是ACE_SOCK_Stream、ACE_SOCK_Acceptor和ACE_SOCK_Connector,结构如图2-1所示。

                                                                         图2-1 Socket封装器结构图

其中:

  • ACE_SOCK_Stream 表示一条由通信双方建立的通信流,它之进行I/O操作,需要一个Socket描述符,保存在ACE_IPC_SAP类的数据成员handle_中。
  • ACE_SOCK_Connector只进行主动连接操作,连接的Socket描述符保存在ACE_SOCK_Stream中。每一个连接都有一个ACE_SOCK_Stream对象,用于后续的I/O操作。
  • ACE_SOCK_Acceptor只用于被动连接。被动连接需要一个侦听的Scoket描述符,同样也保存在ACE_IPC_SAP类的handle_中。

2.1 Socket IPC分析

进程间通信(IPC)是操作系统提供的一个非常重要的功能。进程间通信的方式非常多,如用于远程通信的Socket接口、TLI接口,用于本机通信的SVR4 STREAM管道、UNIX FIFO、Windows命名管道等。为了将这些不同的进程间通信方式封装成面向对象的接口,ACE设计了一个IPC Wrapper Facader组件,用于简化通信软件的开发。而ACE_IPC_SAP类是ACE IPC Wrapper Facader继承结构的根基类。其实ACE_IPC_SAP类除了图2-1中的ACE_SOCK类、ACE_FIFO类外,还有ACE_SPIPE、ACE_TLI等其他类,它们都用于不同形式的进程间通信。

ACE_IPC_SAP类主要有两个功能:一个是包含一个数据成员handle_,用于保存文件描述符;另一个是提供成员函数用于基本的I/O属性操作。ACE_IPC_SAP类代码清单如下:

// 代码在ace/IPC_SAP.h文件中

#ifndef ACE_IPC_SAP_H
#define ACE_IPC_SAP_H
#include /**/ "ace/pre.h"

#include "ace/Flag_Manip.h"
#include "ace/os_include/sys/os_types.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

class ACE_Export ACE_IPC_SAP
{
public:

  /// Interface for <ioctl>.
  int control (int cmd, void *) const;

  // = Common I/O handle options related to sockets.

  /**
   * Enable asynchronous I/O (ACE_SIGIO), urgent data (ACE_SIGURG),
   * non-blocking I/O (ACE_NONBLOCK), or close-on-exec (ACE_CLOEXEC),
   * which is passed as the @a value.
   */
  int enable (int value) const;

  /**
   * Disable asynchronous I/O (ACE_SIGIO), urgent data (ACE_SIGURG),
   * non-blocking I/O (ACE_NONBLOCK), or close-on-exec (ACE_CLOEXEC),
   * which is passed as the @a value.
   */
  int disable (int value) const;

  /// Get the underlying handle.
  ACE_HANDLE get_handle (void) const;

  /// Set the underlying handle.
  void set_handle (ACE_HANDLE handle);

  /// Dump the state of an object.
  void dump (void) const;

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

protected:

  // = Ensure that ACE_IPC_SAP is an abstract base class.
  /// Default constructor.
  ACE_IPC_SAP (void);

  /// Protected destructor.
  /**
   * Not a virtual destructor.  Protected destructor to prevent
   * operator delete() from being called through a base class
   * ACE_IPC_SAP pointer/reference.
   */
  ~ACE_IPC_SAP (void);

private:
  /// Underlying I/O handle. handle_是I/O操作的文件描述符
  ACE_HANDLE handle_;

  /// Cache the process ID. pid_用于保存进程号
  static pid_t pid_;
};

ACE_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
#include "ace/IPC_SAP.inl"
#endif /* __ACE_INLINE__ */

#include /**/ "ace/post.h"
#endif /* ACE_IPC_SAP_H */

(1)ACE_IPC_SAP类的构造函数和析构函数都是protected类型的。这样可以防止ACE_IPC_SAP被直接实例化,使它可以成为一个抽象类。

(2)ACE_IPC_SAP类用两个重要的函数:enable函数和disable函数,用于设置和取消描述符的属性。由于它们完全属于文件属性操作。

(3)ACE_SOCK是ACE_IPC_SAP类的子类,用于实现基于Socket接口的通信方式。它的主要功能是创建Socket和设置Socket属性。ACE_SOCK类的open函数用于创建Socket,并且将描述符保存在父类的handle_数据成员中。open函数有两种重置的形式,以适应不同的平台,代码清单如下:

// 代码在ace/SOCK.h中
  /// Wrapper around the BSD-style @c socket system call (no QoS).
  int open (int type,
            int protocol_family,
            int protocol,
            int reuse_addr);

  /// Wrapper around the QoS-enabled @c WSASocket function.
  int open (int type,
            int protocol_family,
            int protocol,
            ACE_Protocol_Info *protocolinfo,
            ACE_SOCK_GROUP g,
            u_long flags,
            int reuse_addr);

2.2 ACE_SOCK_Acceptor类的分析

ACE_SOCK_Acceptor类用于被动连接端,它的作用是建立侦听Socket,等待客户端的连接。应用程序通过open函数建立侦听的Socket,通过accept函数等待客户端的连接。ACE_SOCK_Acceptor类的代码清单如下:

// 代码在ace/SOCK_Acceptor.h中

#ifndef ACE_SOCK_ACCEPTOR_H
#define ACE_SOCK_ACCEPTOR_H
#include /**/ "ace/pre.h"

#include "ace/SOCK_Stream.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

class ACE_Time_Value;
class ACE_Accept_QoS_Params;

class ACE_Export ACE_SOCK_Acceptor : public ACE_SOCK
{
public:
  // = Initialization and termination methods.
  /// Default constructor.
  ACE_SOCK_Acceptor (void);

  /**
   * Initialize a passive-mode BSD-style acceptor socket (no QoS).
   * @a local_sap is the address that we're going to listen for
   * connections on.  If @a reuse_addr is 1 then we'll use the
   * @c SO_REUSEADDR to reuse this address.
   */
  ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
                     int reuse_addr = 0,
                     int protocol_family = PF_UNSPEC,
                     int backlog = ACE_DEFAULT_BACKLOG,
                     int protocol = 0);

  /// Initialize a passive-mode QoS-enabled acceptor socket.  Returns 0
  /// on success and -1 on failure.
  ACE_SOCK_Acceptor (const ACE_Addr &local_sap,
                     ACE_Protocol_Info *protocolinfo,
                     ACE_SOCK_GROUP g,
                     u_long flags,
                     int reuse_addr,
                     int protocol_family = PF_UNSPEC,
                     int backlog = ACE_DEFAULT_BACKLOG,
                     int protocol = 0);

  /**
   * Initialize a passive-mode BSD-style acceptor socket (no QoS).
   * @a local_sap is the address that we're going to listen for
   * connections on.  If @a reuse_addr is 1 then we'll use the
   * @c SO_REUSEADDR to reuse this address.  Returns 0 on success and
   * -1 on failure.
   */
  int open (const ACE_Addr &local_sap,
            int reuse_addr = 0,
            int protocol_family = PF_UNSPEC,
            int backlog = ACE_DEFAULT_BACKLOG,
            int protocol = 0);

  /// Initialize a passive-mode QoS-enabled acceptor socket.  Returns 0
  /// on success and -1 on failure.
  int open (const ACE_Addr &local_sap,
            ACE_Protocol_Info *protocolinfo,
            ACE_SOCK_GROUP g,
            u_long flags,
            int reuse_addr,
            int protocol_family = PF_UNSPEC,
            int backlog = ACE_DEFAULT_BACKLOG,
            int protocol = 0);

  /// Close the socket.  Returns 0 on success and -1 on failure.
  int close (void);

  /// Default dtor.
  ~ACE_SOCK_Acceptor (void);

  // = Passive connection <accept> methods.
  /**
   * Accept a new ACE_SOCK_Stream connection.  A @a timeout of 0
   * means block forever, a @a timeout of {0, 0} means poll.  @a restart
   * == true means "restart if interrupted," i.e., if errno == EINTR.
   * Note that @a new_stream inherits the "blocking mode" of @c this
   * ACE_SOCK_Acceptor, i.e., if @c this acceptor factory is in
   * non-blocking mode, the @a new_stream will be in non-blocking mode
   * and vice versa.
   */
  int accept (ACE_SOCK_Stream &new_stream,
              ACE_Addr *remote_addr = 0,
              ACE_Time_Value *timeout = 0,
              bool restart = true,
              bool reset_new_handle = false) const;

#if !defined (ACE_HAS_WINCE)
  /**
   * Accept a new ACE_SOCK_Stream connection using the QoS
   * information in @a qos_params.  A @a timeout of 0 means block
   * forever, a @a timeout of {0, 0} means poll.  @a restart == true means
   * "restart if interrupted," i.e., if errno == EINTR.  Note that
   * @a new_stream inherits the "blocking mode" of @c this
   * ACE_SOCK_Acceptor, i.e., if @c this acceptor factory is in
   * non-blocking mode, the @a new_stream will be in non-blocking mode
   * and vice versa.
   */
  int accept (ACE_SOCK_Stream &new_stream,
              ACE_Accept_QoS_Params qos_params,
              ACE_Addr *remote_addr = 0,
              ACE_Time_Value *timeout = 0,
              bool restart = true,
              bool reset_new_handle = false) const;
#endif  // ACE_HAS_WINCE

  // = Meta-type info
  typedef ACE_INET_Addr PEER_ADDR;
  typedef ACE_SOCK_Stream PEER_STREAM;

  /// Dump the state of an object.
  void dump (void) const;

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

protected:
  /// Perform operations that must occur before <ACE_OS::accept> is
  /// called.
  int shared_accept_start (ACE_Time_Value *timeout,
                           bool restart,
                           int &in_blocking_mode) const;

  /// Perform operations that must occur after <ACE_OS::accept> is
  /// called.
  int shared_accept_finish (ACE_SOCK_Stream new_stream,
                            int in_blocking_mode,
                            bool reset_new_handle) const;

  /**
   * This method factors out the common <open> code and is called by
   * both the QoS-enabled <open> method and the BSD-style <open>
   * method.
   */
  int shared_open (const ACE_Addr &local_sap,
                   int protocol_family,
                   int backlog);

private:
  /// Do not allow this function to percolate up to this interface...
  int get_remote_addr (ACE_Addr &) const;
};

ACE_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
#include "ace/SOCK_Acceptor.inl"
#endif /* __ACE_INLINE__ */

#include /**/ "ace/post.h"
#endif /* ACE_SOCK_ACCEPTOR_H */

(1)open函数

open函数用于建立一个侦听的Socket。它将Socket编程中的多个接口绑定在一个函数中,为应用程序隐藏了Socket编程的细节。

(2)accept函数

accept函数被应用程序调用,用来等待和接收客户端的连接。

(3)close函数

如果应用程序明确要关闭侦听的Socket,可以调用close()函数。ACE_SOCK_Stream、ACE_SOCK_Acceptor等类中,它们的析构函数都是空函数,而文件的关闭则必须放在close函数中。这是ACE的一种设计方式,只有应用程序明确调用close函数才关闭文件,这样可以避免在析构函数中出现自动关闭的情况。

2.3 ACE_SOCK_Connector类的分析

ACE_SOCK_Connector类用于客户端发起一个新连接,它的结构和ACE_SOCK_Acceptor非常相似。ACE_SOCK_Connector没有关闭函数,它的析构函数也为空,因为新连接的Socket句柄保存在ACE_SOCK_Stream对象中,由它负责关闭。

ACE_SOCK_Connector类只负责connect操作。

// 代码在ace/SOCK_Connector.h

#ifndef ACE_SOCK_CONNECTOR_H
#define ACE_SOCK_CONNECTOR_H
#include /**/ "ace/pre.h"

#include "ace/SOCK_Stream.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

class ACE_QoS_Params;
class ACE_Time_Value;

/**
 * @class ACE_SOCK_Connector
 *
 * @brief Defines a factory that actively connects to a remote IP
 * address and TCP port, creating a new @c ACE_SOCK_Stream object.
 *
 * The @c ACE_SOCK_Connector doesn't have a socket of its own,
 * i.e., it simply "borrows" the one from the @c ACE_SOCK_Stream
 * that's being connected.  The reason for this is that the
 * underlying socket API doesn't use a factory socket to connect
 * data mode sockets.  Therefore, there's no need to inherit
 * @c ACE_SOCK_Connector from @c ACE_SOCK.  A nice side-effect of
 * this is that @c ACE_SOCK_Connector objects do not store state so
 * they can be used reentrantly in multithreaded programs.
 */
class ACE_Export ACE_SOCK_Connector
{
public:
  /// Default constructor.
  ACE_SOCK_Connector (void);

  /**
   * Actively connect to a peer, producing a connected @c ACE_SOCK_Stream
   * object if the connection succeeds.
   *
   * @param new_stream  The @c ACE_SOCK_Stream object that will be connected
   *                    to the peer.
   * @param remote_sap  The address that we are trying to connect to.
   *                    The protocol family of @c remote_sap is used for
   *                    the connected socket. That is, if @c remote_sap
   *                    contains an IPv6 address, a socket with family
   *                    PF_INET6 will be used, else it will be PF_INET.
   * @param timeout     Pointer to an @c ACE_Time_Value object with amount
   *                    of time to wait to connect. If the pointer is 0
   *                    then the call blocks until the connection attempt
   *                    is complete, whether it succeeds or fails.  If
   *                    *timeout == {0, 0} then the connection is done
   *                    using nonblocking mode.  In this case, if the
   *                    connection can't be made immediately, this method
   *                    returns -1 and errno == EWOULDBLOCK.
   *                    If *timeout > {0, 0} then this is the maximum amount
   *                    of time to wait before timing out; if the specified
   *                    amount of time passes before the connection is made,
   *                    this method returns -1 and errno == ETIME. Note
   *                    the difference between this case and when a blocking
   *                    connect is attempted that TCP times out - in the latter
   *                    case, errno will be ETIMEDOUT.
   * @param local_sap   (optional) The local address to bind to.  If it's
   *                    the default value of @c ACE_Addr::sap_any then the
   *                    OS will choose an unused port.
   * @param reuse_addr  (optional) If the value is 1, the local address
   *                    (@c local_sap) is reused, even if it hasn't been
   *                    cleaned up yet.
   * @param flags       Ignored.
   * @param perms       Ignored.
   * @param protocol    (optional) If value is 0, default SOCK_STREAM
   *                    protocol is selected by kernel (typically TCP).
   */
  ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
                      const ACE_Addr &remote_sap,
                      const ACE_Time_Value *timeout = 0,
                      const ACE_Addr &local_sap = ACE_Addr::sap_any,
                      int reuse_addr = 0,
                      int flags = 0,
                      int perms = 0,
                      int protocol = 0);

#if !defined (ACE_HAS_WINCE)
  /**
   * Actively connect to a peer, producing a connected @c ACE_SOCK_Stream
   * object if the connection succeeds.
   *
   * @param new_stream  The @c ACE_SOCK_Stream object that will be connected
   *                    to the peer.
   * @param remote_sap  The address that we are trying to connect to.
   *                    The protocol family of @c remote_sap is used for
   *                    the connected socket. That is, if @c remote_sap
   *                    contains an IPv6 address, a socket with family
   *                    PF_INET6 will be used, else it will be PF_INET.
   * @param qos_params  Contains QoS parameters that are passed to the
   *                    IntServ (RSVP) and DiffServ protocols.
   *                    @see ACE_QoS_Params.
   * @param timeout     Pointer to an @c ACE_Time_Value object with amount
   *                    of time to wait to connect. If the pointer is 0
   *                    then the call blocks until the connection attempt
   *                    is complete, whether it succeeds or fails.  If
   *                    *timeout == {0, 0} then the connection is done
   *                    using nonblocking mode.  In this case, if the
   *                    connection can't be made immediately, this method
   *                    returns -1 and errno == EWOULDBLOCK.
   *                    If *timeout > {0, 0} then this is the maximum amount
   *                    of time to wait before timing out; if the specified
   *                    amount of time passes before the connection is made,
   *                    this method returns -1 and errno == ETIME. Note
   *                    the difference between this case and when a blocking
   *                    connect is attempted that TCP times out - in the latter
   *                    case, errno will be ETIMEDOUT.
   * @param local_sap   (optional) The local address to bind to.  If it's
   *                    the default value of @c ACE_Addr::sap_any then the
   *                    OS will choose an unused port.
   * @param reuse_addr  (optional) If the value is 1, the local address
   *                    (@c local_sap) is reused, even if it hasn't been
   *                    cleaned up yet.
   * @param flags       Ignored.
   * @param perms       Ignored.
   */
  ACE_SOCK_Connector (ACE_SOCK_Stream &new_stream,
                      const ACE_Addr &remote_sap,
                      ACE_QoS_Params qos_params,
                      const ACE_Time_Value *timeout = 0,
                      const ACE_Addr &local_sap = ACE_Addr::sap_any,
                      ACE_Protocol_Info *protocolinfo = 0,
                      ACE_SOCK_GROUP g = 0,
                      u_long flags = 0,
                      int reuse_addr = 0,
                      int perms = 0);
#endif  // ACE_HAS_WINCE

  /**
   * Actively connect to a peer, producing a connected @c ACE_SOCK_Stream
   * object if the connection succeeds.
   *
   * @param new_stream  The @c ACE_SOCK_Stream object that will be connected
   *                    to the peer.
   * @param remote_sap  The address that we are trying to connect to.
   *                    The protocol family of @c remote_sap is used for
   *                    the connected socket. That is, if @c remote_sap
   *                    contains an IPv6 address, a socket with family
   *                    PF_INET6 will be used, else it will be PF_INET.
   * @param timeout     Pointer to an @c ACE_Time_Value object with amount
   *                    of time to wait to connect. If the pointer is 0
   *                    then the call blocks until the connection attempt
   *                    is complete, whether it succeeds or fails.  If
   *                    *timeout == {0, 0} then the connection is done
   *                    using nonblocking mode.  In this case, if the
   *                    connection can't be made immediately, this method
   *                    returns -1 and errno == EWOULDBLOCK.
   *                    If *timeout > {0, 0} then this is the maximum amount
   *                    of time to wait before timing out; if the specified
   *                    amount of time passes before the connection is made,
   *                    this method returns -1 and errno == ETIME. Note
   *                    the difference between this case and when a blocking
   *                    connect is attempted that TCP times out - in the latter
   *                    case, errno will be ETIMEDOUT.
   * @param local_sap   (optional) The local address to bind to.  If it's
   *                    the default value of @c ACE_Addr::sap_any then the
   *                    OS will choose an unused port.
   * @param reuse_addr  (optional) If the value is 1, the local address
   *                    (@c local_sap) is reused, even if it hasn't been
   *                    cleaned up yet.
   * @param flags       Ignored.
   * @param perms       Ignored.
   * @param protocol    (optional) If value is 0, default SOCK_STREAM
   *                    protocol is selected by kernel (typically TCP).
   *
   * @return            Returns 0 if the connection succeeds. If it fails,
   *                    -1 is returned and errno contains a specific error
   *                    code.
   */
  int connect (ACE_SOCK_Stream &new_stream,
               const ACE_Addr &remote_sap,
               const ACE_Time_Value *timeout = 0,
               const ACE_Addr &local_sap = ACE_Addr::sap_any,
               int reuse_addr = 0,
               int flags = 0,
               int perms = 0,
               int protocol = 0);

#if !defined (ACE_HAS_WINCE)
  /**
   * Actively connect to a peer, producing a connected @c ACE_SOCK_Stream
   * object if the connection succeeds.
   *
   * @param new_stream  The @c ACE_SOCK_Stream object that will be connected
   *                    to the peer.
   * @param remote_sap  The address that we are trying to connect to.
   *                    The protocol family of @c remote_sap is used for
   *                    the connected socket. That is, if @c remote_sap
   *                    contains an IPv6 address, a socket with family
   *                    PF_INET6 will be used, else it will be PF_INET.
   * @param qos_params  Contains QoS parameters that are passed to the
   *                    IntServ (RSVP) and DiffServ protocols.
   *                    @see ACE_QoS_Params.
   * @param timeout     Pointer to an @c ACE_Time_Value object with amount
   *                    of time to wait to connect. If the pointer is 0
   *                    then the call blocks until the connection attempt
   *                    is complete, whether it succeeds or fails.  If
   *                    *timeout == {0, 0} then the connection is done
   *                    using nonblocking mode.  In this case, if the
   *                    connection can't be made immediately, this method
   *                    returns -1 and errno == EWOULDBLOCK.
   *                    If *timeout > {0, 0} then this is the maximum amount
   *                    of time to wait before timing out; if the specified
   *                    amount of time passes before the connection is made,
   *                    this method returns -1 and errno == ETIME. Note
   *                    the difference between this case and when a blocking
   *                    connect is attempted that TCP times out - in the latter
   *                    case, errno will be ETIMEDOUT.
   * @param local_sap   (optional) The local address to bind to.  If it's
   *                    the default value of @c ACE_Addr::sap_any then the
   *                    OS will choose an unused port.
   * @param reuse_addr  (optional) If the value is 1, the local address
   *                    (@c local_sap) is reused, even if it hasn't been
   *                    cleaned up yet.
   * @param flags       Ignored.
   * @param perms       Ignored.
   *
   * @return            Returns 0 if the connection succeeds. If it fails,
   *                    -1 is returned and errno contains a specific error
   *                    code.
   */
  int connect (ACE_SOCK_Stream &new_stream,
               const ACE_Addr &remote_sap,
               ACE_QoS_Params qos_params,
               const ACE_Time_Value *timeout = 0,
               const ACE_Addr &local_sap = ACE_Addr::sap_any,
               ACE_Protocol_Info *protocolinfo = 0,
               ACE_SOCK_GROUP g = 0,
               u_long flags = 0,
               int reuse_addr = 0,
               int perms = 0);
#endif  // ACE_HAS_WINCE

  /// Default destructor.
  ~ACE_SOCK_Connector (void);

  // = Completion routine.
  /**
   * Try to complete a nonblocking connection that was begun by a
   * previous call to connect with a {0, 0} ACE_Time_Value timeout.
   * @see connect().
   *
   * @param new_stream  The @c ACE_SOCK_Stream object that will be connected
   *                    to the peer.
   * @param remote_sap  If non-0, it points to the @c ACE_INET_Addr object
   *                    that will contain the address of the connected peer.
   * @param timeout     Same values and return value possibilites as for
   *                    connect(). @see connect().
   */
  int complete (ACE_SOCK_Stream &new_stream,
                ACE_Addr *remote_sap = 0,
                const ACE_Time_Value *timeout = 0);

  /// Resets any event associations on this handle
  bool reset_new_handle (ACE_HANDLE handle);

  // = Meta-type info
  typedef ACE_INET_Addr PEER_ADDR;
  typedef ACE_SOCK_Stream PEER_STREAM;

  /// Dump the state of an object.
  void dump (void) const;

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

protected:
  /// Perform operations that ensure the socket is opened using
  /// BSD-style semantics (no QoS).
  int shared_open (ACE_SOCK_Stream &new_stream,
                   int protocol_family,
                   int protocol,
                   int reuse_addr);

  /// Perform operations that ensure the socket is opened using
  /// QoS-enabled semantics.
  int shared_open (ACE_SOCK_Stream &new_stream,
                   int protocol_family,
                   int protocol,
                   ACE_Protocol_Info *protocolinfo,
                   ACE_SOCK_GROUP g,
                   u_long flags,
                   int reuse_addr);

  /// Perform operations that must be called before <ACE_OS::connect>.
  int shared_connect_start (ACE_SOCK_Stream &new_stream,
                            const ACE_Time_Value *timeout,
                            const ACE_Addr &local_sap);

  /// Perform operations that must be called after <ACE_OS::connect>.
  int shared_connect_finish (ACE_SOCK_Stream &new_stream,
                             const ACE_Time_Value *timeout,
                             int result);
};

ACE_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
#include "ace/SOCK_Connector.inl"
#endif /* __ACE_INLINE__ */

#include /**/ "ace/post.h"
#endif /* ACE_SOCK_CONNECTOR_H */

【源码并没有仔细看看,就是粗粗的浏览了一下,网络编程的基础不牢靠,还是有些看不懂。先记录下来,做一个学习的标记。】

参考文献:

[1] ACE技术内幕:深入解析ACE架构设计与实现原理

猜你喜欢

转载自blog.csdn.net/XingyuZhengtu/article/details/83899722
ACE