码迷,mamicode.com
首页 > 其他好文 > 详细

网络编程入门08

时间:2019-08-08 13:19:06      阅读:87      评论:0      收藏:0      [点我收藏+]

标签:换行   多个   char*   std   mod   网络   else   iter   turn   

net模块

Callbacks.h

template<typename T>
inline T* get_pointer(const std::shared_ptr<T>& ptr)   //返回shard_ptr的裸指针,感觉意义不大的一个函数
{
  return ptr.get();
}

template<typename T>
inline T* get_pointer(const std::unique_ptr<T>& ptr)  //返回unique_ptr的裸指针
{
  return ptr.get();
}

template<typename To, typename From>                     //对智能指针进行转换
inline ::std::shared_ptr<To> down_pointer_cast(const ::std::shared_ptr<From>& f) {
  if (false)
  {
    implicit_cast<From*, To*>(0);
  }

#ifndef NDEBUG
  assert(f == NULL || dynamic_cast<To*>(get_pointer(f)) != NULL);
#endif
  return ::std::static_pointer_cast<To>(f);
}

typedef std::shared_ptr<TcpConnection> TcpConnectionPtr;                  
typedef std::function<void()> TimerCallback;
typedef std::function<void (const TcpConnectionPtr&)> ConnectionCallback;  //对于一个含有TcpConnection智能指针的对象座位参数的可调用对象,起不同的别名。 可调用对象,就是一种回调函数
typedef std::function<void (const TcpConnectionPtr&)> CloseCallback;
typedef std::function<void (const TcpConnectionPtr&)> WriteCompleteCallback;
typedef std::function<void (const TcpConnectionPtr&, size_t)> HighWaterMarkCallback;

// the data has been read to (buf, len)
typedef std::function<void (const TcpConnectionPtr&,
                            Buffer*,
                            Timestamp)> MessageCallback;

void defaultConnectionCallback(const TcpConnectionPtr& conn);
void defaultMessageCallback(const TcpConnectionPtr& conn,
                            Buffer* buffer,
                            Timestamp receiveTime);

Endian.h

linux系统在endian.h头文件中提供了更多的函数进行主机字节和大小端字节序的相互转换,如下:
//在已经知道自己系统的字节序前提下,调用这些函数会更快点
uint16_t htobe16(uint16_t host_16bits);

uint16_t htole16(uint16_t host_16bits);

uint16_t be16toh(uint16_t big_endian_16bits);

uint16_t le16toh(uint16_t little_endian_16bits);

 

uint32_t htobe32(uint32_t host_32bits);

uint32_t htole32(uint32_t host_32bits);

uint32_t be32toh(uint32_t big_endian_32bits);

uint32_t le32toh(uint32_t little_endian_32bits);

 

uint64_t htobe64(uint64_t host_64bits);

uint64_t htole64(uint64_t host_64bits);

uint64_t be64toh(uint64_t big_endian_64bits);

uint64_t le64toh(uint64_t little_endian_64bits);
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);
}

Buffer.h

/// A buffer class modeled after org.jboss.netty.buffer.ChannelBuffer
///
/// @code
/// +-------------------+------------------+------------------+
/// | prependable bytes |  readable bytes  |  writable bytes  |
/// |                   |     (CONTENT)    |                  |
/// +-------------------+------------------+------------------+
/// |                   |                  |                  |
/// 0      <=      readerIndex   <=   writerIndex    <=     size

calss Buffer{
private:
  vector<char> buffer_;
  size_t readerIndex_;
  size_t writerIndex_;
  static const char kCRLF[] = "\r\n"; //在.cc文件里定义的
public:
  static const size_t kCheapPrepend = 8;
  static const size_t kInitialSize = 1024;

  explicit Buffer(size_t initialSize = kInitialSize)
    : buffer_(kCheapPrepend + initialSize),
      readerIndex_(kCheapPrepend),
      writerIndex_(kCheapPrepend)
  {
    assert(readableBytes() == 0);
    assert(writableBytes() == initialSize);
    assert(prependableBytes() == kCheapPrepend);
  }
  void swap(Buffer& rhs);//交换操作 三个变量交换
  size_t readableBytes() const;//可以读的数据量
  size_t writableBytes() const;//可以写的数据量
  size_t prependableBytes() const;//前置数据量
  const char* peek() const;//可以读的点
  const char* findCRLF() const;//在数据区中搜索KCRLF
  {
    const char* crlf = std::search(start, beginWrite(), kCRLF, kCRLF+2);
    return crlf == beginWrite() ? NULL : crlf;//找到返回字符串点,找不到返回空
  }
  const char* findEOL() const {  //寻找换行符
       //C 库函数 void *memchr(const void *str, int c, size_t n) 在参数 str 所指向的字符串的前 n 个字节中搜索第一次出现字符 c(一个无符号字符)的位置。
    const void* eol = memchr(peek(), '\n', readableBytes());  
    return static_cast<const char*>(eol);
  }
  const char* findEOL(const char* start) const;//送start处寻找EOL
  void retrieve(size_t len)//取数据
  void retrieveUntil(const char* end)//从数据头到end取数据
  void retrieveInt64();  //就是把读索引前移
  void retrieveInt32()
  void retrieveInt16() 
  void retrieveInt8()
   void retrieveAll()//取所有数据
  string retrieveAllAsString() //取所有数据,返回string
  string retrieveAsString(size_t len);//取一部分数据以string返回
  StringPiece toStringPiece() const;//数据与stringpiece返回
  void append(const char* /*restrict*/ data, size_t len);//写数据
  //还有很多写数据的操作
  int64_t readInt64() {
    int64_t result = peekInt64();  //读Int64_t
    retrieveInt64(); //读索引前移
    return result;// 返回
  }
  int64_t peekInt64() const  //读8个字节的数据
  {
    assert(readableBytes() >= sizeof(int64_t));
    int64_t be64 = 0;
    ::memcpy(&be64, peek(), sizeof be64);
    return sockets::networkToHost64(be64);  //从网络字节序换为本地字节序
  }
  void prependInt8(int8_t x)//加Int8
  {
    prepend(&x, sizeof x);
  }
  void prepend(const void* /*restrict*/ data, size_t len) //往缓冲区前加数据
  {
    assert(len <= prependableBytes());
    readerIndex_ -= len;
    const char* d = static_cast<const char*>(data);
    std::copy(d, d+len, begin()+readerIndex_);
  }
  void shrink(size_t reserve); //在保存未读数据的情况下,预留reserve个字节
  size_t internalCapacity() const //返回缓冲区的大小
  ssize_t readFd(int fd, int* savedErrno) {
      char extrabuf[65536];
      struct iovec vec[2];
      const size_t writable = writableBytes();
      vec[0].iov_base = begin()+writerIndex_;
      vec[0].iov_len = writable;
      vec[1].iov_base = extrabuf;
      vec[1].iov_len = sizeof extrabuf;
      // when there is enough space in this buffer, don't read into extrabuf.
      // when extrabuf is used, we read 128k-1 bytes at most.
      const int iovcnt = (writable < sizeof extrabuf) ? 2 : 1; 
      const ssize_t n = sockets::readv(fd, vec, iovcnt);  //readv和writev函数用于在一次函数调用中读、写多个非连续缓冲区。有时也将这两个函数称为散布读(scatter read)和聚集写    (gather write)。
    /*
    #include <sys/uio.h>
    ssize_t readv(int filedes, const struct iovec *iov, int iovcnt);             //从一个文件描述符,读数据,可能写在多个缓冲区 从0,1,2,3慢慢写
    ssize_t writev(int filedes, const struct iovec *iov, int iovcnt);
    两个函数的返回值:若成功则返回已读、写的字节数,若出错则返回-1
   */
      if (n < 0)
      {
        *savedErrno = errno;
      }
      else if (implicit_cast<size_t>(n) <= writable)
      {
        writerIndex_ += n;
      }
      else      //如果数据比较小的地区,就需要继续从extrabuf读数据
      {
        writerIndex_ = buffer_.size();
        append(extrabuf, n - writable);
      }
  
      return n;


  }

}

网络编程入门08

标签:换行   多个   char*   std   mod   网络   else   iter   turn   

原文地址:https://www.cnblogs.com/aiqingyi/p/11320256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!