封装时 send 函数为啥使用 const string & buf 作为参数类型
bool send(const string &buffer) // buffer不要用const char *
const string & buf
既可以接收 string
也可以接受 char *
. 估计是对
char *
进行了隐式转换成了 string
.
send 函数的参数为啥是 buf.data() 和 buf.size(), 而不是 buf.c_str() 和 buf.length
if ((::send(m_clientfd,buffer.data(),buffer.size(),0))<=0) return false;
buf.data()
和buf.c_str()
都指向的是内容的指针,但是语义不一样。 data 表示的就是原始数据,而 c_str 表示的是转化为char *
.buf.size()
的语义是原始内容的大小,而length
表示的是字符串的长度。
所以都是因为语义不合适。虽然都能用,但是确实不合适。
recv 函数的参数为啥是 & buf[0] 而不是 buf.c_str() 或者 buf.data()
int readn=::recv(m_clientfd,&buffer[0],buffer.size(),0); // 直接操作buffer的内存。
因为后面两种返回的都是带有 const
, 只有 &buf[0]
才没有 const
, 适合对内容进行修改。
recv 函数对字符串手动操作的注意点:
// 接收服务端的报文,成功返回true,失败返回false。
// buffer-存放接收到的报文的内容,maxlen-本次接收报文的最大长度。
bool recv(string &buffer,const size_t maxlen)
{ // 如果直接操作string对象的内存,必须保证:1)不能越界;2)操作后手动设置数据的大小。
buffer.clear(); // 清空容器。
buffer.resize(maxlen); // 设置容器的大小为maxlen。
int readn=::recv(m_clientfd,&buffer[0],buffer.size(),0); // 直接操作buffer的内存。
if (readn<=0) { buffer.clear(); return false; }
buffer.resize(readn); // 重置buffer的实际大小。
return true;
}
- 写入之前,=resize= 的空间一定要够,不能越界。
- 写入之后,根据写入的数据量,重新通过
resize
来把空间调整为接收到的数据量,方便后续的string
操作。