2016-10-04 68 views
-1

我用做在服務器端的插口上一次失敗的關閉:在什麼情況下在前臺或後臺完成關機/關閉?

struct linger so_linger; 
so_linger.l_onoff = 1; 
so_linger.l_linger = 0; 
setsockopt(s, SOL_SOCKET, SO_LINGER, &so_linger, socklen_t)sizeof(so_linger)); 

shutdown(s, SHUT_WR); 
close(s); 

哪裏s是我關閉套接字。

它的工作原理,但我有時遇到問題,它似乎影響一些服務器,而不是其他人。一些在Ubuntu上運行,一些在CoreOS上運行。它在CoreOS上運行良好。

在Ubuntu上,儘管關閉了調用,但我仍然從與套接字相關的epoll_wait中獲取了一個事件。

我認爲這會立即發生。但是,如果你使用非阻塞I/O,我想這可能不是這種情況。

它基本上意味着我在epoll_wait中獲得了一個ev.data.ptr值集合中指向已被銷燬的事件的事件。

所以,問題是,這是真的嗎?半關閉不會從epoll中刪除事件描述符,並且關閉將不會與非阻塞I/O同步?

因此,如果我不再需要事件,我應該實際上用EPOLL_CTL_DEL手動刪除描述符?

+0

您正在發送FIN然後是RST。爲什麼? – EJP

+0

@EJP - 你的意思是這不是在做一個失敗的關閉?它似乎雖然工作。 – Matt

回答

0

關閉套接字並將其從epoll集中清除。但有一個警告。參照epoll man page

> Q6 Will closing a file descriptor cause it to be removed from all 
      epoll sets automatically? 

    A6 Yes, but be aware of the following point. A file descriptor is a 
     reference to an open file description (see open(2)). Whenever a 
     file descriptor is duplicated via dup(2), dup2(2), fcntl(2) 
     F_DUPFD, or fork(2), a new file descriptor referring to the same 
     open file description is created. An open file description 
     continues to exist until all file descriptors referring to it 
     have been closed. A file descriptor is removed from an epoll set 
     only after all the file descriptors referring to the underlying 
     open file description have been closed (or before if the file 
     descriptor is explicitly removed using epoll_ctl(2) 
     EPOLL_CTL_DEL).This means that even after a file descriptor 
     that is part of an epoll set has been closed, events may be 
     reported for that file descriptor if other file descriptors 
     referring to the same underlying file description remain open. 

因此,有報道其close被稱爲插座上的事件的可能性。不確定您的測試是否適合您的測試,在某些平臺上可以正常工作。當然,我不認爲這與異步I/O有關。

相關問題