Socket封装(31)

来源:互联网 发布:福州seo基础培训 编辑:程序博客网 时间:2024/06/09 17:41
  1. Endian.h
    封装了字节序转换函数(全局函数,位于muduo::net::sockets名称空间中)。

  2. SocketsOps.h/ SocketsOps.cc
    封装了socket相关系统调用(全局函数,位于muduo::net::sockets名称空间中)。

  3. Socket.h/Socket.cc(Socket类)
    用RAII方法封装socket file descriptor

  4. InetAddress.h/InetAddress.cc(InetAddress类)
    网际地址sockaddr_in封装






Endian头文件

endian.h

// Copyright 2010, Shuo Chen.  All rights reserved.// http://code.google.com/p/muduo///// Use of this source code is governed by a BSD-style license// that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com)//// This is a public header file, it must only include public header files.#ifndef MUDUO_NET_ENDIAN_H#define MUDUO_NET_ENDIAN_H#include <stdint.h>#include <endian.h>namespace muduo{namespace net{namespace sockets{// the inline assembler code makes type blur,// so we disable warnings for a while.#if __GNUC_MINOR__ >= 6#pragma GCC diagnostic push#endif#pragma GCC diagnostic ignored "-Wconversion"#pragma GCC diagnostic ignored "-Wold-style-cast"inline uint64_t hostToNetwork64(uint64_t host64){  return htobe64(host64);}inline uint32_t hostToNetwork32(uint32_t host32){  return htobe32(host32);}inline uint16_t hostToNetwork16(uint16_t host16){  return htobe16(host16);}inline uint64_t networkToHost64(uint64_t net64){  return be64toh(net64);}inline uint32_t networkToHost32(uint32_t net32){  return be32toh(net32);}inline uint16_t networkToHost16(uint16_t net16){  return be16toh(net16);}#if __GNUC_MINOR__ >= 6#pragma GCC diagnostic pop#else#pragma GCC diagnostic error "-Wconversion"#pragma GCC diagnostic error "-Wold-style-cast"#endif}}}#endif  // MUDUO_NET_ENDIAN_H



InetAddress头文件

inetaddress.h


// Copyright 2010, Shuo Chen.  All rights reserved.// http://code.google.com/p/muduo///// Use of this source code is governed by a BSD-style license// that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com)//// This is a public header file, it must only include public header files.#ifndef MUDUO_NET_INETADDRESS_H#define MUDUO_NET_INETADDRESS_H#include <muduo/base/copyable.h>#include <muduo/base/StringPiece.h>#include <netinet/in.h>namespace muduo{namespace net{////// Wrapper of sockaddr_in.////// This is an POD interface class.class InetAddress : public muduo::copyable{ public:  /// Constructs an endpoint with given port number.  /// Mostly used in TcpServer listening.  // 仅仅指定port,不指定ip,则ip为INADDR_ANY(即0.0.0.0)  explicit InetAddress(uint16_t port);  /// Constructs an endpoint with given ip and port.  /// @c ip should be "1.2.3.4"  InetAddress(const StringPiece& ip, uint16_t port);  /// Constructs an endpoint with given struct @c sockaddr_in  /// Mostly used when accepting new connections  InetAddress(const struct sockaddr_in& addr)    : addr_(addr)  { }  string toIp() const;  string toIpPort() const;  // __attribute__ ((deprecated)) 表示该函数是过时的,被淘汰的  // 这样使用该函数,在编译的时候,会发出警告  /* 保留这个函数的原因是 为了 软件升级使用,最后不要调用这个函数,直接调用toIpPort就行了*/  string toHostPort() const __attribute__ ((deprecated))  { return toIpPort(); }  // default copy/assignment are Okay  const struct sockaddr_in& getSockAddrInet() const { return addr_; }  void setSockAddrInet(const struct sockaddr_in& addr) { addr_ = addr; }  uint32_t ipNetEndian() const { return addr_.sin_addr.s_addr; }  uint16_t portNetEndian() const { return addr_.sin_port; } private:  struct sockaddr_in addr_;};}}#endif  // MUDUO_NET_INETADDRESS_H


InetAddress源文件

inetaddress.cc


// Copyright 2010, Shuo Chen.  All rights reserved.// http://code.google.com/p/muduo///// Use of this source code is governed by a BSD-style license// that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com)#include <muduo/net/InetAddress.h>#include <muduo/net/Endian.h>#include <muduo/net/SocketsOps.h>#include <strings.h>  // bzero#include <netinet/in.h>#include <boost/static_assert.hpp>// INADDR_ANY use (type)value casting.#pragma GCC diagnostic ignored "-Wold-style-cast"static const in_addr_t kInaddrAny = INADDR_ANY;#pragma GCC diagnostic error "-Wold-style-cast"//     /* Structure describing an Internet socket address.  *///     struct sockaddr_in {//         sa_family_t    sin_family; /* address family: AF_INET *///         uint16_t       sin_port;   /* port in network byte order *///         struct in_addr sin_addr;   /* internet address *///     };//     /* Internet address. *///     typedef uint32_t in_addr_t;//     struct in_addr {//         in_addr_t       s_addr;     /* address in network byte order *///     };using namespace muduo;using namespace muduo::net;BOOST_STATIC_ASSERT(sizeof(InetAddress) == sizeof(struct sockaddr_in));InetAddress::InetAddress(uint16_t port){  bzero(&addr_, sizeof addr_);  addr_.sin_family = AF_INET;  addr_.sin_addr.s_addr = sockets::hostToNetwork32(kInaddrAny);  addr_.sin_port = sockets::hostToNetwork16(port);}InetAddress::InetAddress(const StringPiece& ip, uint16_t port){  bzero(&addr_, sizeof addr_);  sockets::fromIpPort(ip.data(), port, &addr_);}string InetAddress::toIpPort() const{  char buf[32];  sockets::toIpPort(buf, sizeof buf, addr_);  return buf;}string InetAddress::toIp() const{  char buf[32];  sockets::toIp(buf, sizeof buf, addr_);  return buf;}




Sokcet头文件

Socket.h


// Copyright 2010, Shuo Chen.  All rights reserved.// http://code.google.com/p/muduo///// Use of this source code is governed by a BSD-style license// that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com)//// This is an internal header file, you should not include this.#ifndef MUDUO_NET_SOCKET_H#define MUDUO_NET_SOCKET_H#include <boost/noncopyable.hpp>namespace muduo{////// TCP networking.///namespace net{class InetAddress;////// Wrapper of socket file descriptor.////// It closes the sockfd when desctructs./// It's thread safe, all operations are delagated to OS.class Socket : boost::noncopyable{ public:  explicit Socket(int sockfd)    : sockfd_(sockfd) //已已经初始化的sockfd  { }  // Socket(Socket&&) // move constructor in C++11  ~Socket();  int fd() const { return sockfd_; }  /// abort if address in use  void bindAddress(const InetAddress& localaddr);  /// abort if address in use  void listen();  /// On success, returns a non-negative integer that is  /// a descriptor for the accepted socket, which has been  /// set to non-blocking and close-on-exec. *peeraddr is assigned.  /// On error, -1 is returned, and *peeraddr is untouched.  int accept(InetAddress* peeraddr);  void shutdownWrite();  ///  /// Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm).  ///  // Nagle算法可以一定程度上避免网络拥塞  // TCP_NODELAY选项可以禁用Nagle算法  // 禁用Nagle算法,可以避免连续发包出现延迟,这对于编写低延迟的网络服务很重要  void setTcpNoDelay(bool on);  ///  /// Enable/disable SO_REUSEADDR  ///  void setReuseAddr(bool on);  ///  /// Enable/disable SO_KEEPALIVE  ///  // TCP keepalive是指定期探测连接是否存在,如果应用层有心跳的话,这个选项不是必需要设置的  void setKeepAlive(bool on); private:  const int sockfd_;};}}#endif  // MUDUO_NET_SOCKET_H

Socket源文件

Socket.cc

// Copyright 2010, Shuo Chen.  All rights reserved.// http://code.google.com/p/muduo///// Use of this source code is governed by a BSD-style license// that can be found in the License file.// Author: Shuo Chen (chenshuo at chenshuo dot com)#include <muduo/net/Socket.h>#include <muduo/net/InetAddress.h>#include <muduo/net/SocketsOps.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <strings.h>  // bzerousing namespace muduo;using namespace muduo::net;Socket::~Socket(){  sockets::close(sockfd_);}void Socket::bindAddress(const InetAddress& addr){  sockets::bindOrDie(sockfd_, addr.getSockAddrInet());}void Socket::listen(){  sockets::listenOrDie(sockfd_);}int Socket::accept(InetAddress* peeraddr){  struct sockaddr_in addr;  bzero(&addr, sizeof addr);  int connfd = sockets::accept(sockfd_, &addr);  if (connfd >= 0)  {    peeraddr->setSockAddrInet(addr);  }  return connfd;}void Socket::shutdownWrite(){  sockets::shutdownWrite(sockfd_);}void Socket::setTcpNoDelay(bool on){  int optval = on ? 1 : 0;  ::setsockopt(sockfd_, IPPROTO_TCP, TCP_NODELAY,               &optval, sizeof optval);  // FIXME CHECK}void Socket::setReuseAddr(bool on){  int optval = on ? 1 : 0;  ::setsockopt(sockfd_, SOL_SOCKET, SO_REUSEADDR,               &optval, sizeof optval);  // FIXME CHECK}void Socket::setKeepAlive(bool on){  int optval = on ? 1 : 0;  ::setsockopt(sockfd_, SOL_SOCKET, SO_KEEPALIVE,               &optval, sizeof optval);  // FIXME CHECK}



程序程序

#include <muduo/net/InetAddress.h>//#define BOOST_TEST_MODULE InetAddressTest#define BOOST_TEST_MAIN#define BOOST_TEST_DYN_LINK#include <boost/test/unit_test.hpp>using muduo::string;using muduo::net::InetAddress;BOOST_AUTO_TEST_CASE(testInetAddress){  InetAddress addr1(1234);  BOOST_CHECK_EQUAL(addr1.toIp(), string("0.0.0.0"));  BOOST_CHECK_EQUAL(addr1.toIpPort(), string("0.0.0.0:1234"));  InetAddress addr2("1.2.3.4", 8888);  BOOST_CHECK_EQUAL(addr2.toIp(), string("1.2.3.4"));  BOOST_CHECK_EQUAL(addr2.toIpPort(), string("1.2.3.4:8888"));  InetAddress addr3("255.255.255.255", 65535);  BOOST_CHECK_EQUAL(addr3.toIp(), string("255.255.255.255"));  BOOST_CHECK_EQUAL(addr3.toIpPort(), string("255.255.255.255:65535"));}

程序输出


原创粉丝点击