test SO_RCVTIMEO and MSG_WAITALL
1.首先两者都运用于阻塞的情景下,对nonblock的fd不起作用。
2.SO_RCVTIMEO, socket选项,作为getsockopt, setsockopt的参数。见下 figure1.
SO_RCVTIMEO选项可以指定阻塞调用的超时时长,SO_RCVTIMEO的影响的函数read, readv, recv, recvfrom, recvmsg.
3.MSG_WAITALL, recv调用的参数,
MSG_WAITALL
On SOCK_STREAM sockets this requests that the function block
until the full amount of data can be returned. The function may
return the smaller amount of data if the socket is a message-
based socket, if a signal is caught, if the connection is termi‐
nated, if MSG_PEEK was specified, or if an error is pending for
the socket.
ps:
recv(sockfd, buff, buff_size, MSG_WAITALL),
在正常情况下recv 是会等待直到读取到buff_size 长度的数据,但是这里的WAITALL 也只是尽量读全,在有中断的情况下recv 还是可能会被打断,造成没有读完指定的buff_size的长度。
所以即使是采用recv + WAITALL 参数还是要考虑是否需要循环读取的问题,在实验中对于多数情况下recv (使用了MSG_WAITALL)还是可以读完buff_size,所以相应的性能会比直接read 进行循环读要好一些。
阅读原文.-> https://blog.csdn.net/kai8wei/article/details/77479240
figure1.

//test.......
//recv(s_sock, buffer, SIZE_BUFFER - 1, MSG_WAITALL)
//setsockopt(s_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))
#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<sys/wait.h>
#include<netinet/in.h>
#include<string.h>
#include<errno.h>
#include<arpa/inet.h>
#include<fcntl.h>
#define PORT 32767
#define NUM_LISTEN 20
#define SIZE_BUFFER 1024
int main()
{
pid_t pid = 0;
int s_sock = 0;
sockaddr_in s_addr;
//create socket.
s_sock = socket(AF_INET, SOCK_STREAM, 0);
if(-1 == s_sock){
std::cout<<"call socket faild."<<std::endl;
return -1;
}
//bind socket.
bzero(&s_addr, sizeof(s_addr));
s_addr.sin_family = AF_INET;
s_addr.sin_addr.s_addr = inet_addr("118.25.216.246");
s_addr.sin_port = htons(PORT);
//setsockopt SO_RCVTIMEO
timeval tv;
tv.tv_sec = 2;
tv.tv_usec = 0;
if(-1 == setsockopt(s_sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv))){
std::cout<<"call setsockopt faild."<<std::endl;
return -1;
}
std::cout<<"set SO_RCVTIMEO."<<std::endl;
int iRet = connect(s_sock, (sockaddr*)&s_addr, sizeof(s_addr));
if(-1 == iRet){//error occured.
std::cout<<"call connect faild. error code: "<<errno<<std::endl;
std::cout<<"error descriptions: \n\t"<<strerror(errno)<<std::endl;
return iRet;
}
//send msg.
//char* msg = "hello";
//write(s_sock, msg, strlen(msg));
//set socket nonblock.
// int flags = fcntl(s_sock, F_GETFL, 0);
// flags |= O_NONBLOCK;
// fcntl(s_sock, F_SETFL, flags);
//recv msg.
char buffer[SIZE_BUFFER];
bzero(buffer, SIZE_BUFFER);
std::cout<<"ready read."<<std::endl;
int n = 0;
while(true)
if(0 < (n = recv(s_sock, buffer, SIZE_BUFFER - 1, MSG_WAITALL))){//read buffer.
std::cout<<buffer<<std::endl;
return -1;
}
else
std::cout<<"continue"<<std::endl;
return 0;
}