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;
}