p69:SocketStream封装
基于之前写的序列化模块封装了读和写,但是socket
的API
并不保证一定能够写或读到规定的字节数,所以封装了readFixSize
、writeFixSize
保证一定操作规定字节的数据。
class Stream
基本读写操作
// 读操作,保存到buffer中
virtual int read(void* buffer, size_t length) = 0;
// 读操作,保存到ByteArray中
virtual int read(ByteArray::ptr ba, size_t length) = 0;
// 写操作,从buffer中写
virtual int write(const void* buffer, size_t length) = 0;
// 写操作,从ByteArray中写
virtual int write(ByteArray::ptr ba, size_t length) = 0;
readFixSize
// 读固定长度的数据,读取到内存
int Stream::readFixSize(void* buffer, size_t length) {
// 偏移量
size_t offset = 0;
// 读取长度
int64_t left = length;
while(left > 0) {
// len表示已经读取的数据大小
int64_t len = read((char*)buffer + offset, left);
// 异常
if(len <= 0) {
return len;
}
// 更新偏移量
offset += len;
// 更新剩余读取长度
left -= len;
}
// 返回读取到内存中的数据长度
return length;
}
// 读固定长度的数据,读取到ByteArray 因为ByteArray对象内部有一个位置指针,所以不需要手动更新偏移量
int Stream::readFixSize(ByteArray::ptr ba, size_t length) {
int64_t left = length;
while(left > 0) {
int64_t len = read(ba, left);
if(len <= 0) {
return len;
}
left -= len;
}
return length;
}
writeFixSize
// 写固定长度的数据,从内存写
int Stream::writeFixSize(const void* buffer, size_t length) {
size_t offset = 0;
int64_t left = length;
while(left > 0) {
int64_t len = write((const char*)buffer + offset, left);
if(len <= 0) {
return len;
}
offset += len;
left -= len;
}
return length;
}
// 写固定长度的数据,从ByteArray写
int Stream::writeFixSize(ByteArray::ptr ba, size_t length) {
int64_t left = length;
while(left > 0) {
int64_t len = write(ba, left);
if(len <= 0) {
return len;
}
left -= len;
}
return length;
}
class SocketStream
成员函数
/// Socket类
Socket::ptr m_socket;
/// 是否主控
bool m_owner;
read
// 读数据,读取到内存
int SocketStream::read(void* buffer, size_t length) {
if(!isConnected()) {
return -1;
}
return m_socket->recv(buffer, length);
}
// 读数据,读取到ByteArray
int SocketStream::read(ByteArray::ptr ba, size_t length) {
if(!isConnected()) {
return -1;
}
std::vector<iovec> iovs;
ba->getWriteBuffers(iovs, length);
int rt = m_socket->recv(&iovs[0], iovs.size());
if(rt > 0) {
ba->setPosition(ba->getPosition() + rt);
}
return rt;
}
write
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->getReadBuffers(iovs, length);
int rt = m_socket->send(&iovs[0], iovs.size());
if(rt > 0) {
ba->setPosition(ba->getPosition() + rt);
}
return rt;
}