0

我试图实现 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 设置保持活动选项有什么问题吗?

4

2 回答 2

0

SO_KEEPALIVE 用于面向连接的套接字。所以请先连接你的套接字,然后设置 SO_KEEPALIVE。

于 2020-09-30T04:58:34.463 回答
0

从涵盖套接字选项的socket(7)文档中:SO_XXX

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

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

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

int16_t如今,您用作选项类型的like 不太可能与int典型系统上的大小相同,因此会出现错误。改为使用int

于 2020-09-30T04:59:11.777 回答