启用TCP保持活动选项时获取无效参数作为失败原因吗?

时间:2020-09-30 04:24:03

标签: linux tcp tcp-keepalive

我尝试实现TCP客户端以发送TCP保持活动请求,但所有选项均失败,并带有无效参数。我的代码如下所示:

    #define SERVER_ADDRESS "94.23.3.169" /* Server address */
    #define PORT 1010/* the port client will be connecting to */
    
    
    static int16_t i16Sockfd;
    
    void vEnablekeepalive(int16_t i16Sockfd;)
    {
        int16_t i16Enable;
        socklen_t optlen = sizeof(i16Enable);
    
        /* Check the status for the keepalive option */
        if(getsockopt(i16Sockfd, SOL_SOCKET, SO_KEEPALIVE, &i16Enable, &optlen) < 0) {
            perror("getsockopt");
        }
        MSG("Before KEEP_ALIVE OPTION:%d\n",i16Enable);
    
        i16Enable = 1;
        if(setsockopt(i16Sockfd, SOL_SOCKET, SO_KEEPALIVE, &i16Enable, sizeof(i16Enable)) == -1){
            perror("setsockopt");
        }
    
        /* Check the status for the keepalive option */
        if(getsockopt(i16Sockfd, SOL_SOCKET, SO_KEEPALIVE, &i16Enable, &optlen) < 0) {
            perror("getsockopt);
        }
        MSG("After KEEP_ALIVE OPTION:%d\n",i16Enable);
    
        int16_t i16Idle = 600;
        if(setsockopt(i16Sockfd, IPPROTO_TCP, TCP_KEEPIDLE, &i16Idle, sizeof(i16Idle)) == -1){
            perror("Idle");
        }
    
        int16_t i16Interval = 60;
        if(setsockopt(i16Sockfd, IPPROTO_TCP, TCP_KEEPINTVL, &i16Interval, sizeof(i16Interval)) == -1){
            perror("Interval");
        }
    
        int16_t i16Maxcount = 5;
        if(setsockopt(i16Sockfd, IPPROTO_TCP, TCP_KEEPCNT, &i16Maxcount, sizeof(i16Maxcount)) == -1){
            perror("Maxcount");
        }
    }
    
    int main()
    {
        struct sockaddr_in their_addr;
        
        if ((i16Sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == -1) {
            perror("socket");
        }
              
        Enablekeepalive(i16Sockfd);
    
        their_addr.sin_family = AF_INET; /* host byte order */
        their_addr.sin_port = htons(PORT); /* short, network byte order */
        their_addr.sin_addr.s_addr = inet_addr(SERVER_ADDRESS);
        zero(&(their_addr.sin_zero), 8); /* zero the rest of the struct */
        if (connect(i16Sockfd, (struct sockaddr*) &their_addr,sizeof(struct sockaddr)) == -1) {
            perror("connect");
            close(i16Sockfd);
        }
              
    }

我不明白为什么它为所有 setsockopt API给出了无效的参数。使用setsockopt设置保持活动选项有什么错误吗?

2 个答案:

答案 0 :(得分:0)

SO_KEEPALIVE用于面向连接的套接字。因此,请先连接您的套接字,然后再设置SO_KEEPALIVE。

答案 1 :(得分:0)

来自socket(7) documentation,涵盖了SO_XXX套接字选项:

可以使用setsockopt(2)设置下面列出的套接字选项,并使用getsockopt(2)读取所有套接字的套接字级别设置为SOL_SOCKET除非另有说明,否则optval是指向整数的指针。

SO_KEEPALIVE 启用在面向连接的套接字上发送保持活动消息。 期望一个整数布尔值标志。

特定于Linux的TCP_KEEPIDLE等选项也需要一个int参数。

这些天,像您正在用作选项类型的int16_t不太可能与典型系统上的int大小相同,因此会出现错误。请改用int