首页 > 解决方案 > 设置套接字超时时是否以微秒为单位四舍五入超时值

问题描述

#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
    
void print_hex(const char *string)
{
    unsigned char *p = (unsigned char *) string;
    int i;
    
    for (i=0; i < strlen(string); ++i) {
        if (! (i % 16) && i)
            printf("\n");
    
        printf("0x%02x ", p[i]);
    }
    printf("\n\n");
}
    
struct timeval_test{
    long tv_sec;
    long tv_usec;
};

int main()
{
    int sock_ret;
    char ex_recv_timeout[32]={0};
    char des_recv_timeout[32]={1,0};
    int ex_size = sizeof(ex_recv_timeout);
        
    int sockfd = socket(AF_INET,SOCK_STREAM,0);
    int ret;
    
    struct timeval_test tv_existing;
    struct timeval_test tv_desired;
    socklen_t existing_len = sizeof(tv_existing);
    socklen_t new_len = sizeof(tv_desired);
    tv_desired.tv_sec=3;
    tv_desired.tv_usec=4010;
        
    if(sockfd == -1)
    {
        printf("Socket not created");
    }
    printf("Sockfd : %d\n",sockfd);
    
    recv(sockfd,ex_recv_timeout,32,0)   ;
    
    sock_ret = getsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv_existing, &existing_len);
    printf("sock_ret = %d , &tv_existing.sec = %d, &tv_existing.usec = %d, &existing_len = %d \n",sock_ret,tv_existing.tv_sec,tv_existing.tv_usec,existing_len);    
    
    sock_ret = setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv_desired, new_len);
    printf("sock_ret = %d , &new_timeout.sec = %d, &new_timeout.usec = %d, &new_len = %d \n",sock_ret,tv_desired.tv_sec,tv_desired.tv_usec,new_len);
    
    existing_len = sizeof(tv_existing);
    
    sock_ret = getsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv_existing, &existing_len);
    printf("sock_ret = %d , &tv_existing.sec = %d, &tv_existing.usec = %d, &existing_len = %d \n",sock_ret,tv_existing.tv_sec,tv_existing.tv_usec,existing_len);
        
    tv_desired.tv_sec=0;
    tv_desired.tv_usec=0;
            
    sock_ret = setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv_desired, new_len);
    printf("sock_ret = %d , &new_timeout.sec = %d, &new_timeout.usec = %d, &new_len = %d \n",sock_ret,tv_desired.tv_sec,tv_desired.tv_usec,new_len);
    
    existing_len = sizeof(tv_existing);
    
    sock_ret = getsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &tv_existing, &existing_len);
    printf("sock_ret = %d , &tv_existing.sec = %d, &tv_existing.usec = %d, &existing_len = %d \n",sock_ret,tv_existing.tv_sec,tv_existing.tv_usec,existing_len);
    
    return 0;
}

上面的代码创建一个套接字,设置一个超时并获取超时。我看到以微秒为单位的超时值在不同的平台上四舍五入,如下所示......其中第二行具有要设置的值,而第三行是获取的值。这种差异是由于平台还是特定于机器?

On Linux 64 it is : 
sock_ret = 0 , &tv_existing.sec = 0, &tv_existing.usec = 0, &existing_len = 16
sock_ret = 0 , &new_timeout.sec = 3, &new_timeout.usec = 4010, &new_len = 16
sock_ret = 0 , &tv_existing.sec = 3, &tv_existing.usec = 8000, &existing_len = 16
sock_ret = 0 , &new_timeout.sec = 0, &new_timeout.usec = 0, &new_len = 16
sock_ret = 0 , &tv_existing.sec = 0, &tv_existing.usec = 0, &existing_len = 16

On HP 64 it is 
sock_ret = 0 , &tv_existing.sec = 0, &tv_existing.usec = 0, &existing_len = 4
sock_ret = 0 , &new_timeout.sec = 3, &new_timeout.usec = 4010, &new_len = 8
sock_ret = 0 , &tv_existing.sec = 3, &tv_existing.usec = 0, &existing_len = 4
sock_ret = 0 , &new_timeout.sec = 0, &new_timeout.usec = 0, &new_len = 8
sock_ret = 0 , &tv_existing.sec = 0, &tv_existing.usec = 0, &existing_len = 4

On Aix 64 it is :
sock_ret = 0 , &tv_existing.sec = 0, &tv_existing.usec = 0, &existing_len = 16
sock_ret = 0 , &new_timeout.sec = 3, &new_timeout.usec = 4010, &new_len = 16
sock_ret = 0 , &tv_existing.sec = 3, &tv_existing.usec = 4010, &existing_len = 16
sock_ret = 0 , &new_timeout.sec = 0, &new_timeout.usec = 0, &new_len = 16
sock_ret = 0 , &tv_existing.sec = 0, &tv_existing.usec = 0, &existing_len = 16

On Power 8 it is : 
sock_ret = 0 , &tv_existing.sec = 0, &tv_existing.usec = 0, &existing_len = 16
sock_ret = 0 , &new_timeout.sec = 3, &new_timeout.usec = 4010, &new_len = 16
sock_ret = 0 , &tv_existing.sec = 3, &tv_existing.usec = 10000, &existing_len = 16
sock_ret = 0 , &new_timeout.sec = 0, &new_timeout.usec = 0, &new_len = 16
sock_ret = 0 , &tv_existing.sec = 0, &tv_existing.usec = 0, &existing_len = 16

标签: csockets

解决方案


推荐阅读