2011-02-22 48 views
1

我实现了套接字超时和重试,但为了做到这一点,我不得不将套接字设置为非阻塞套接字。但是,我需要套接字来阻止。这是我对解决这两个问题的尝试。这不起作用。后续发送呼叫阻止但从不发送任何数据。当我没有选择和超时连接时,后续发送呼叫正常工作。套接字超时并删除O_NONBLOCK选项

参考文献:

代码:

fd_set fdset; 
struct timeval tv; 
fcntl(dsock, F_SETFL, O_NONBLOCK); 
tv.tv_sec = theDeviceTimeout; 
tv.tv_usec = 0; 
int retries=0; 
logi(theLogOutput, LOG_INFO, "connecting to device socket num retrys: %i", theDeviceRetry); 
for(retries=0;retries<theDeviceRetry;retries++) { 
    connect(dsock, (struct sockaddr *)&daddr, sizeof daddr); 


    FD_ZERO(&fdset); 
    FD_SET(dsock, &fdset); 
    if (select(dsock + 1, NULL, &fdset, NULL, &tv) == 1) { 
     int so_error; 
     socklen_t slen = sizeof so_error; 
     getsockopt(dsock, SOL_SOCKET, SO_ERROR, &so_error, &slen); 
     if (so_error == 0) { 
      logi(theLogOutput, LOG_INFO, "connected to socket on port %i on %s", theDevicePort, theDeviceIP); 
      break; 
     } else { 
      logi(theLogOutput, LOG_WARN, "connect to %i failed on ip %s because %s retries %i", theDevicePort, theDeviceIP, strerror(errno), retries); 
      logi(theLogOutput, LOG_WARN, "failed to connect to device %s", strerror(errno)); 
      logi(theLogOutput, LOG_WARN, "error: %i %s", so_error, strerror(so_error)); 
      continue; 
     } 
    } 
} 

int opts; 
opts = fcntl(dsock,F_GETFL); 
logi(theLogOutput, LOG_DEBUG, "clearing nonblock option %i retries %i", opts, retries); 
opts ^= O_NONBLOCK; 
fcntl(dsock, F_SETFL, opts); 
+0

我们需要你发布一个可以编译和运行的完整测试用例。 – zwol 2011-02-22 22:41:05

+0

是否最后一次调用'fcntl'成功(返回值为0)?如果不是,那么将errno设置为? – 2011-02-22 22:45:15

+0

请注意,您应该使用'opts | = O_NONBLOCK',因为XOR不会告诉您它是ON还是OFF。另外......一旦'retries == theDeviceRetry'真的发生了什么? – 2015-12-06 02:27:46

回答

1

后你可写的事件,没有错误,那么你需要再打电话connect(),如记录。这会告诉您连接是成功还是失败。

+0

它在哪里“记录”? – 2013-10-06 16:20:48

0

为什么不使用SO_RCVTIMEOSO_SNDTIMEO套接字选项?或者我错过了你的问题?