[英]Setting a timeout when using connect() in C++
我在 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
}
使套接字成為非阻塞套接字,然后使用帶有超時值的 select() 或 poll() 來檢查可寫性。 如果 select() 返回超時您沒有及時連接,您可以關閉套接字並處理連接失敗。 如果它以完成返回,則一切正常,您可以繼續。
看看這個新聞組帖子,其中包含有關如何在 Linux 中對套接字連接設置超時的詳細信息和示例代碼。 基本思想是使用非阻塞套接字,然后等待連接。
為您的套接字設置非阻塞模式並使用select
檢查連接是否建立。 這是樣本
另一種沒有 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;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.