记录一下最近这学期学习的sylar服务器框架项目,输出整理一下项目的结构,用到的知识和自己的体会
项目仓库地址
https://github.com/sylar-yin/sylar/
整理博客过程中参考的大佬资料链接:
============================================
基础介绍
Stream模块提供了字节流读写接口,包括一个Stream基类以及封装了Socket类的子类SocketStream类
提供了void*类型作为buffer以及ByteArray::ptr类型作为buffer的两套接口
// 字节流读写类(基类)
class Stream {
public:
typedef std::shared_ptr
<Stream> ptr;
virtual ~Stream() {}
virtual int read(void* buffer, size_t length) = 0; // 读到buffer中
virtual int read(ByteArray::ptr ba, size_t length) = 0; // 读到ByteArray中
virtual int readFixSize(void* buffer, size_t length); // 读固定长度到buffer中
virtual int readFixSize(ByteArray::ptr ba, size_t length); // 读固定长度到ByteArray中
virtual int write(const void* buffer, size_t length) = 0; // 从buffer中写
virtual int write(ByteArray::ptr ba, size_t length) = 0; // 从ByteArray中写
virtual int writeFixSize(const void* buffer, size_t length); // 从buffer中写固定长度
virtual int writeFixSize(ByteArray::ptr ba, size_t length); // 从ByteArray中写固定长度
virtual void close() = 0; // 关闭流
};
// 字节流读写类(socket实现子类)
class SocketStream : public Stream {
public:
typedef std::shared_ptr
<SocketStream> ptr;
SocketStream(Socket::ptr sock, bool owner = true);
~SocketStream();
virtual int read(void* buffer, size_t length) override; // 读到buffer
virtual int read(ByteArray::ptr ba, size_t length) override; // 读到ByteArray
virtual int write(const void* buffer, size_t length) override; // 从buffer写
virtual int write(ByteArray::ptr ba, size_t length) override; // 从ByteArray写
virtual void close() override; // 关闭流
Socket::ptr getSocket() const { return m_socket; }
bool isConnected() const;
protected:
Socket::ptr m_socket; // sylar::Socket类成员
bool m_owner; // 是否自主控制socket
};
读/写固定长度方法
基类Stream唯一实现的方法,读写固定长度,如果不够继续循环读写
这里实现代码中的read/write方法要等待子类实现
int Stream::readFixSize(void* buffer, size_t length) {
size_t offset = 0;
size_t left = length;
while(left > 0) {
size_t len = read((char*)buffer + offset, left);
if(len <= 0) {
return len;
}
offset += len;
left -= len;
}
return length;
}
int Stream::readFixSize(ByteArray::ptr ba, size_t length) {
size_t left = length;
while(left > 0) {
size_t len = read(ba, left);
if(len <= 0) {
return len;
}
left -= len;
}
return length;
}
int Stream::writeFixSize(const void* buffer, size_t length) {
size_t offset = 0;
size_t left = length;
while(left > 0) {
size_t len = write((const char*)buffer + offset, left);
if(len <= 0) {
return len;
}
offset += len;
left -= len;
}
return length;
}
int Stream::writeFixSize(ByteArray::ptr ba, size_t length) {
size_t left = length;
while(left > 0) {
size_t len = write(ba, left);
if(len <= 0) {
return len;
}
left -= len;
}
return length;
}
SocketStream子类实现
构造/析构函数
初始化/关闭socket,同时记录socketfd是否为stream所有
SocketStream::SocketStream(Socket::ptr sock, bool owner)
:m_socket(sock)
,m_owner(owner) {
}
SocketStream::~SocketStream() {
if(m_owner && m_socket) {
m_socket->close();
}
}
read/write实现
底层封装了Socket类的方法
int SocketStream::read(void* buffer, size_t length) {
if(!isConnected()) {
return -1;
}
return m_socket->recv(buffer, length);
}
int SocketStream::read(ByteArray::ptr ba, size_t length) {
if(!isConnected()) {
return -1;
}
std::vector
<iovec> iovs;
ba->getWriteBuffer(iovs, length);
int rt = m_socket->recv(&iovs[0], iovs.size());
if(rt > 0) {
ba->setPosition(ba->getPosition() + rt);
}
return rt;
}
int SocketStream::write(const void* buffer, size_t length) {
if(!isConnected()) {
return -1;
}
return m_socket->send(buffer, length);
}
int SocketStream::write(ByteArray::ptr ba, size_t length) {
if(!isConnected()) {
return -1;
}
std::vector
<iovec> iovs;
ba->getWriteBuffer(iovs, length);
int rt = m_socket->send(&iovs[0], iovs.size());
if(rt > 0) {
ba->setPosition(ba->getPosition() + rt);
}
return rt;
}
总结
提供了统一的流接口,方便后续使用以及扩展




严肃学习中……