在 C++ 中使用 connect() 时设置超时

发布于 2024-08-08 18:22:48 字数 1943 浏览 2 评论 0原文

我在 linux 上使用 c++ 中的套接字使用 connect() 连接到服务器,但它似乎没有超时值。给它几秒钟的超时时间的最简单/最好的方法是什么?我将发布我所拥有的代码,包括对 connect() 的阻塞调用:

using namespace std;
int main( int argc, char* argv[] )
{
  // Interpret the command line arguments
  string uri_string = "";

  if ( argc != 2 )
  {
    cerr << "Usage: " << argv[0];
    cerr << " <URI>" << endl;
    return 1;
  }
  else
  {
    uri_string = argv[1];
  }

  // Create URI object and have it parse the uri_string
  URI *uri = URI::Parse(uri_string);

  if ( uri == NULL )
  {
    cerr << "Error: Cannot parse URI." << endl;
    return 2;
  }

  // Check the port number specified, if none use port 80
  unsigned port = 80;
  if ( uri->Is_port_defined() )
  {
    port = uri->Get_port();
  }

  // Create TCP socket and connect to server
  int tcp_sock = socket( AF_INET, SOCK_STREAM, 0 );
  if ( tcp_sock < 0 )
  {
    cerr << "Unable to create TCP socket." << endl;
    return 3;
  }

  sockaddr_in server;
  socklen_t slen = sizeof(server);

  server.sin_family = AF_INET;
  server.sin_port = htons( port );
  cout << "Resolving " << uri->Get_host() << "... ";
  hostent *hostp = gethostbyname( uri->Get_host().c_str() );
  memcpy( &server.sin_addr, hostp->h_addr, hostp->h_length );

  struct in_addr **pptr;
  pptr = (struct in_addr **)hostp->h_addr_list;

  string ip_addr = "";
  while( *pptr != NULL ) {
    ip_addr += inet_ntoa(**(pptr++));
  }
  cout << ip_addr << endl;

  cout << "Connecting to " << uri->Get_host() << "|" << ip_addr << "|:";
  cout << port << "... ";
  if ( connect( tcp_sock, (sockaddr*)&server, slen ) < 0 )
  {
    cerr << "Unable to connect to server via TCP." << endl;
    close( tcp_sock );
    return 4;
  }
  cout << "connected." << endl;

  // rest of code
}

I'm using sockets in c++ on linux to connect to a server using connect(), but it doesn't seem to have a timeout value. What would be the easiest/best way to give it a timeout of a few seconds. I'll post the code I have up to, and including, the blocking call to connect():

using namespace std;
int main( int argc, char* argv[] )
{
  // Interpret the command line arguments
  string uri_string = "";

  if ( argc != 2 )
  {
    cerr << "Usage: " << argv[0];
    cerr << " <URI>" << endl;
    return 1;
  }
  else
  {
    uri_string = argv[1];
  }

  // Create URI object and have it parse the uri_string
  URI *uri = URI::Parse(uri_string);

  if ( uri == NULL )
  {
    cerr << "Error: Cannot parse URI." << endl;
    return 2;
  }

  // Check the port number specified, if none use port 80
  unsigned port = 80;
  if ( uri->Is_port_defined() )
  {
    port = uri->Get_port();
  }

  // Create TCP socket and connect to server
  int tcp_sock = socket( AF_INET, SOCK_STREAM, 0 );
  if ( tcp_sock < 0 )
  {
    cerr << "Unable to create TCP socket." << endl;
    return 3;
  }

  sockaddr_in server;
  socklen_t slen = sizeof(server);

  server.sin_family = AF_INET;
  server.sin_port = htons( port );
  cout << "Resolving " << uri->Get_host() << "... ";
  hostent *hostp = gethostbyname( uri->Get_host().c_str() );
  memcpy( &server.sin_addr, hostp->h_addr, hostp->h_length );

  struct in_addr **pptr;
  pptr = (struct in_addr **)hostp->h_addr_list;

  string ip_addr = "";
  while( *pptr != NULL ) {
    ip_addr += inet_ntoa(**(pptr++));
  }
  cout << ip_addr << endl;

  cout << "Connecting to " << uri->Get_host() << "|" << ip_addr << "|:";
  cout << port << "... ";
  if ( connect( tcp_sock, (sockaddr*)&server, slen ) < 0 )
  {
    cerr << "Unable to connect to server via TCP." << endl;
    close( tcp_sock );
    return 4;
  }
  cout << "connected." << endl;

  // rest of code
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

巴黎盛开的樱花 2024-08-15 18:22:48

使套接字成为非阻塞套接字,然后使用带有超时值的 select() 或 poll() 来检查可写性。如果 select() 返回超时,说明您没有及时连接,您可以关闭套接字并处理连接失败。如果返回完成,则一切正常,您可以继续。

Make the socket a non-blocking socket, and then use select() or poll() with a timeout value to check for writability. If the select() returns with a timeout you did not connect in time, and you can close the socket and deal with the connection failure. If it returns with a completion, everything is fine and you can proceed.

心房敞 2024-08-15 18:22:48

为您的套接字设置非阻塞模式,并使用select检查连接是否建立。 这里是示例

set non-blocking mode for your socket and use select to check whether connection established. here is the sample

唠甜嗑 2024-08-15 18:22:48

另一种无需 select() 的痛苦即可实现非阻塞的方法是检查 GetLastError() 是否有 EWOULDBLOCK。

// set socket as nonblocking
unsigned long value = 1;
if (ioctlsocket(yourSocket, FIONBIO, &value) == SOCKET_ERROR)
    return SOCKET_ERROR;

// (call connect here)

// check if connect would block
if (GetLastError() == EWOULDBLOCK)
    return TIMEOUT;

Another way to do non-blocking without the pain of select() is to check GetLastError() for EWOULDBLOCK.

// set socket as nonblocking
unsigned long value = 1;
if (ioctlsocket(yourSocket, FIONBIO, &value) == SOCKET_ERROR)
    return SOCKET_ERROR;

// (call connect here)

// check if connect would block
if (GetLastError() == EWOULDBLOCK)
    return TIMEOUT;
两人的回忆 2024-08-15 18:22:48

查看此新闻组帖子,包含有关如何在 Linux 中对套接字连接设置超时的详细信息和示例代码。基本思想是使用非阻塞套接字,然后等待连接。

Take a look at this newsgroup post, with details and sample code for how to put a timeout on socket connections in Linux. The basic idea is to use non-blocking sockets, and then wait for a connection.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文