再谈 C Socket 发送和接收数据
在之前的文章使用valgrind调试socket发送非字符串数据时的内存泄漏问题中,提到了使用send和recv发送和接收大数据量的方法
#include <sys/types.h>
#include <sys/socket.h>
int recvall (int s,char *buf,int *len)
{
int total = 0;
int bytesleft = *len;
int n;
while (total<*len)
{
n= recv(s,buf+total,bytesleft,0);
if(n==-1){break;}
total += n;
bytesleft -=n;
}
*len = total;
return n==-1?-1:0;
}
int sendall(int s, char *buf, int *len)
{
int total = 0;
int bytesleft = *len;
int n;
while(total < *len) {
n = send(s, buf+total, bytesleft, 0);
if (n == -1) { break; }
total += n;
bytesleft -= n;
}
*len = total;
return n==-1?-1:0;
} 但在实践过程中,发现recvall是有缺陷的。当调用recvall函数时,*len是一个大数值,total为0,total<*len,开始while循环,但是recv始终没有接收到数据,n = recv(s,buf+total,bytesleft,0) = 0,total += n即total始终为0,造成了while死循环。
所以应当将recvall改为以下形式
int recvall(int s, char* buf, int* len)
{
int total = 0;
int bytesleft = *len;
int n;
while ((n = recv(s, buf+ total, bytesleft, 0))>0)
{
total += n;
bytesleft -= n;
if(bytesleft == 0){break;}
}
return n==-1?-1:total;
}当(n = recv(s, buf+ total, bytesleft, 0))>0即接收到数据开始才启动while循环,当剩余的bytesleft的数据等于0时,退出while循环,返回total接收到的整体数据量。
在实际使用时,服务端接收到数据后,才返回数据
int nbytes = 0;
while((nbytes = recvall(sockfd,input_buffer,&need_recv))>0)
{
// ....
// ....
}参考资料:
评论已关闭