1.recv() 和 send() 的缺点
这recv()函数存在可能读取报文不完整的情况,send()存在可能写入数据不完整的情况。
1.1 recv() 函数的改进——Readn()
ssize_t recv(int sockefd, void *buf, size_t len, int flage);
(1)函数的返回值是这次接收到数据的大小。但是你打算读取1000个字节,只能读取100个(TCP存在分包的问题)。要将数据读取完,需要采用循环多次调用这个函数。所以将这个函数改进为 Readn()
(2)Readn() 的声明及参数
bool Readn(const int sockfd,char *buffer,conset size_t n);
1) sockfd:已经准备好的socket连接。
2)buffer:接收数据缓冲区的地址
3)n:本次接收数据的字节数
4)返回值:成功接收到n字节的数据后返回 true ,socket连接不可用返回false。
(3)函数的实现
bool Readn(const int sockfd,char *buffer,conset size_t n)
{
int nLeft,nread,idx;
nLeft = n;
idx = 0;
while(nLeft > 0)
{
if ( (nread = recv(sockfd,buffer + idx,nLeft,0) <= 0) return false;
idx +=nread;
nLeft -= nread;
}
}
1.2 send() 函数的改进——Write()
ssize_t send(int sockefd, const void *buf, size_t len, int flags);
(1)这个函数的返回值是成功发送的字节数。它存在类似 recv 函数的问题。可能由于缓冲区不足等等原因,要写1000个字节,但是成功写入的只有500。
(2)Write() 函数的声明及参数
bool Writen(const int sockfd,const char *buffer,const size_t n);
(3)函数的实现
bool Writen(const int sockfd,const char *buffer,const size_t n)
{
int nLeft,idx,nwrite;
nLeft = n;
idx = 0;
while(nLeft > 0)
{
if ( (nwrite = send(sockfd,buffer + idx,nLeft,0)) <= 0) return false;
nLeft -= nwrite;
idx +=nwrite;
}
return ture;
}