Socket

客户端connect 服务器时候,有可能服务器down掉了,从而导致一直在等connect超时,这个系统时间是21秒左右。我试着用setsockopt去设置connect超时时间,不行 不管用。

    timeval t{3, 1};
    ret = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, &t, sizeof(t));
    ret = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, &t, sizeof(t));
    ret = ::connect(socket, (sockaddr *) &addr, sizeof(addr));

查阅资料,有人提出把socket设为非阻塞然后可以用select限制超时时间

我尝试在linux上测试一下如下,发现确实可以提前Connet TimeOut的时间。


#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <cstring>
#include <cstdio>
#include <errno.h>

int main()
{
    sockaddr_in addr{};
    int socket = ::socket(AF_INET, SOCK_STREAM, 0);

    bzero(&addr, sizeof(addr));

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    addr.sin_port = htons(9999);
    int error = 0, ret = 0;
    char *retStr = nullptr;
    timeval t{3, 0};
    auto set_block = [](int fd, bool block)
    {
        int b = block ? 1 : 0;
        ioctl(fd, FIONBIO, &b);
    };
    set_block(socket, 0);
    ret = ::connect(socket, (sockaddr *)&addr, sizeof(addr));
    if (ret == -1)
    {
        fd_set set;
        FD_ZERO(&set);
        FD_SET(socket, &set);
        if (select(socket + 1, nullptr, &set, nullptr, &t) > 0)
        {
            socklen_t len = sizeof(error);
            getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len);
            if (error != 0)
            {
                retStr = ::strerror(error);
                printf(retStr);
                goto ERROR_SOCKET;
            }
        }
        else
        {
        ERROR_SOCKET:
            //TIMEOUT, set BLOCK
            set_block(socket, 1);
            close(socket);
        }
    }
    return 0;
}
posted @ 2021-11-05 23:27  开学五年级了  阅读(36)  评论(0编辑  收藏  举报