【问题标题】:Trying to connect() multiple times in TCP尝试在 TCP 中多次连接()
【发布时间】:2018-02-25 02:00:58
【问题描述】:

我正在编写一个客户端/服务器应用程序,其中客户端和服务器应通过 TCP 套接字相互发送数据。客户端应该连接到服务器,如果连接失败,它应该等待几秒钟,然后再次尝试连接(最多尝试一定次数)。

这是我目前拥有的代码:

const int i_TRIES = 5;
time_t t_timeout = 3000;
int i_port = 5678;
int i_socket;
string s_IP = "127.0.0.1";

for(int i = 0; i < i_TRIES; i++)
{
    if((i_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    {
        cout << "[Client]: Socket creation failed." << endl;
        exit(EXIT_FAILURE);
    }

    memset(&server_address, '0', sizeof(server_address));

    server_address.sin_family = AF_INET;
    server_address.sin_port = htons(i_port);

    if(inet_pton(AF_INET, s_IP.c_str(), &server_address.sin_addr) <= 0)
    {
        cout << "[Client]: Invalid IP address." << endl;
        exit(EXIT_FAILURE);
    }

    if(connect(i_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0)
    {
        if(i < i_TRIES - 2)
        {
            cout << "[Client]: Connection to server failed. Trying again in " << t_timeout << " ms." << endl;
            close(i_socket);
            sleep(t_timeout);
        } 
        else
        {
            cout << "[Client]: Could not connect to server, exiting." << endl;
            exit(EXIT_FAILURE);
        } 
    } 
    else
    {
        cout << "[Client]: Successfully connected to server." << endl;
        break;
    } 
} 
// do stuff with socket

我遇到的问题是对 connect() 的第一次调用按预期工作,如果没有服务器然后循环重复,它会失败,但是,第二次 connect() 永远阻塞(或至少在很多时候比我想要的要长)。最初,我的循环就在 connect() if 块周围(下面的代码),这也导致了同样的问题。之后我在循环中包含了整个套接字设置(上面的代码),但这也没有帮助。我也尝试在连接失败后关闭套接字,但这也无济于事。

初始for循环:

// other stuff from above here
for(int i = 0; i < i_TRIES; i++)
{
    if(connect(i_socket, (struct sockaddr *)&server_address, sizeof(server_address)) < 0)
    {
        if(i < i_TRIES - 2)
        {
            cout << "[Client]: Connection to server failed. Trying again in " << t_timeout << " ms." << endl;
            sleep(t_timeout);
        } 
        else
        {
            cout << "[Client]: Could not connect to server, exiting." << endl;
            exit(EXIT_FAILURE);
        } 
    } 
    else
    {
        cout << "[Client]: Successfully connected to server." << endl;
        break;
    }
}
// do stuff with socket

我可以强制 connect() 在经过一定时间后返回吗?或者有没有办法让 connect() 函数自己尝试多次?或者我需要对套接字做些什么来重置所有内容,然后才能重试?我希望这不是一个愚蠢的问题,我找不到有关如何多次连接的任何信息。

提前致谢!

【问题讨论】:

    标签: c++ linux sockets network-programming tcp-ip


    【解决方案1】:

    我可以强制connect()在一定时间后返回吗?

    没有。您必须将套接字置于非阻塞模式,然后在等待套接字连接时使用select()(e)poll() 提供超时逻辑。如果连接失败或连接时间过长,请关闭套接字,创建一个新的,然后重试。

    或者有没有办法让connect() 函数自己尝试多次?

    没有。每次调用只能执行 1 次连接尝试。

    或者我需要对套接字做些什么来重置所有内容,然后才能重试?

    无法保证您甚至可以在同一个套接字上多次调用connect()。在某些平台上,您必须在再次调用connect() 之前销毁套接字并创建一个新套接字。您应该养成在所有平台上都这样做的习惯。

    【讨论】:

    • "在某些平台上,您必须在再次调用 connect() 之前销毁套接字并创建一个新套接字" 我可以创建一个临时套接字,然后只需复制 int 变量以将套接字放入我的类变量?
    【解决方案2】:

    将socket设为非阻塞模式,使用select()实现超时。选择套接字上的可写性。请注意,您可以通过这种方式减少平台连接超时,但不能增加它。

    sleep() 毫无意义,简直就是浪费时间。

    【讨论】:

      猜你喜欢
      • 2018-10-21
      • 2011-04-25
      • 2014-05-01
      • 1970-01-01
      • 2020-03-15
      • 2016-11-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多