站在巨人的肩膀上
C++高性能分布式服务器框架
从零开始重写sylar C++高性能分布式服务器框架
概述
- 套接字类,表示一个套接字对象。
- 其实就是在操作系统的 API 上再封装了一层。
Socket
- 继承自 std::enable_shared_from_this 和 sylar::Noncopyable。
- 含有以下属性:
- 文件描述符 m_sock。
- 地址类型(AF_INET,AF_INET6 等)m_family。
- 套接字类型(SOCK_STREAM,SOCK_DGRAM 等)m_tyoe。
- 协议类型(这项其实可以忽略)m_protocol。
- 是否连接(针对 TCP 套接字;如果是 UDP 套接字,则默认已连接)m_isConnected。
- 本地地址 m_localAddress。
- 远端地址 m_remoteAddress。
- 含有如下方法:
- 创建各种类型的套接字对象的方法(TCP 套接字,UDP 套接字,Unix 域套接字)。
- 设置套接字选项,比如超时参数。
- bind / connect / listen 方法,实现绑定地址、发起连接、发起监听功能。
- accept 方法,返回连入的套接字对象。
- 发送和接收数据的方法。
- 获取本地地址和远端地址的方法。
- 获取套接字类型、地址类型、协议类型的方法。
- 取消套接字读、写事件的方法。
SSLSocket
其他说明
- UnixTCPSocket 在 bind 函数里面 connect。
部分相关代码
/**
* @filename socket.h
* @brief Socket 模块
* @author L-ge
* @version 0.1
* @modify 2022-07-09
*/
#ifndef __SYLAR_SOCKET_H__
#define __SYLAR_SOCKET_H__
#include <memory>
#include <netinet/tcp.h>
#include <sys/types.h>
#include <sys/socket.h>
//#include <openssl/err.h>
//#include <openssl/ssl.h>
#include "address.h"
#include "noncopyable.h"
namespace sylar
{
/**
* @brief Socket封装类
*/
class Socket : public std::enable_shared_from_this<Socket>, Noncopyable
{
public:
typedef std::shared_ptr<Socket> ptr;
typedef std::weak_ptr<Socket> weak_ptr;
/**
* @brief Socket类型枚举
*/
enum Type
{
TCP = SOCK_STREAM,
UDP = SOCK_DGRAM,
};
/**
* @brief Socket协议簇枚举
*/
enum Family
{
IPv4 = AF_INET,
IPv6 = AF_INET6,
UNIX = AF_UNIX,
};
static Socket::ptr CreateTCP(sylar::Address::ptr address);
static Socket::ptr CreateUDP(sylar::Address::ptr address);
static Socket::ptr CreateTCPSocket();
static Socket::ptr CreateUDPSocket();
static Socket::ptr CreateTCPSocket6();
static Socket::ptr CreateUDPSocket6();
static Socket::ptr CreateUnixTCPSocket();
static Socket::ptr CreateUnixUDPSocket();
Socket(int family, int type, int protocol = 0);
virtual ~Socket();
/**
* @brief 设置发送超时时间(毫秒)
*/
void setSendTimeout(int64_t v);
int64_t getSendTimeout();
/**
* @brief 设置接受超时时间(毫秒)
*/
void setRecvTimeout(int64_t v);
int64_t getRecvTimeout();
bool getOption(int level, int option, void* result, socklen_t* len);
template<class T>
bool getOption(int level, int option, T& result)
{
socklen_t length = sizeof(T);
return getOption(level, option, &result, &length);
}
bool setOption(int level, int option, const void* result, socklen_t len);
template<class T>
bool setOption(int level, int option, const T& value)
{
return setOption(level, option, &value, sizeof(T));
}
virtual Socket::ptr accept();
virtual bool bind(const Address::ptr addr);
virtual bool connect(const Address::ptr addr, uint64_t timeout_ms = -1);
virtual bool reconnet(uint64_t timeout_ms = -1);
virtual bool listen(int backlog = SOMAXCONN);
virtual bool close();
virtual int send(const void* buffer, size_t length, int flags = 0);
virtual int send(const iovec* buffers, size_t length, int flags = 0);
virtual int sendTo(const void* buffer, size_t length, const Address::ptr to, int flags = 0);
virtual int sendTo(const iovec* buffers, size_t length, const Address::ptr to, int flags = 0);
virtual int recv(void* buffer, size_t length, int flags = 0);
virtual int recv(iovec* buffer, size_t length, int flags = 0);
virtual int recvFrom(void* buffer, size_t length, Address::ptr from, int flags = 0);
virtual int recvFrom(iovec* buffers, size_t length, Address::ptr from, int flags = 0);
/**
* @brief 获取远端地址
*/
Address::ptr getRemoteAddress();
/**
* @brief 获取本地地址
*/
Address::ptr getLocalAddress();
int getFamily() const { return m_family; }
int getType() const { return m_type; }
int getProtocol() const { return m_protocol; }
bool isConnected() const { return m_isConnected; }
/**
* @brief 是否有效(m_sock != -1)
*/
bool isValid() const;
int getError();
/**
* @brief 输出信息到流中
*/
virtual std::ostream& dump(std::ostream& os) const;
virtual std::string toString() const;
int getSocket() const { return m_sock; }
bool cancelRead();
bool cancelWrite();
bool cancelAccept();
bool cancelAll();
protected:
void initSock();
/**
* @brief 创建socket
*/
void newSock();
virtual bool init(int sock);
protected:
/// socket句柄
int m_sock;