您的位置:首页 > 其它

Socket封装(31)

2013-11-07 09:23 351 查看
Endian.h

封装了字节序转换函数(全局函数,位于muduo::net::sockets名称空间中)。

SocketsOps.h/ SocketsOps.cc

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

Socket.h/Socket.cc(Socket类)

用RAII方法封装socket file descriptor

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

[/code]

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

[/code]

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

[/code]

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

[/code]

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>  // bzero

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

[/code]

程序程序

#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"));
}

[/code]
程序输出
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: