udp的close系統調用

    在印象中,是隻有tcp才需要調用close來關閉套接字描述符的,而udp需要與否是無關緊要的。這種直接的印象源於tcp是一個面向連接的協議,而udp則不是。因此對於一條連接,我們需要將其關閉而沒有連接的則不需要。而事實並非如此。

     就剛不久之前,項目遇到了這樣的一個問題:在一個多次循環中,每次循環都會創建一個udp的無連接的套接字,但是循環結束時卻沒有調用close來關閉這個套接字描述符。之後,就出現了一系列的問題。系統貌似阻塞於socket創建(這是我迷惑的地方)。後來纔想起是不是因爲套接字描述符沒有關閉的原因。在增加了close的系統調用之後,系統正常運轉。

       所以是說,即便創建的是udp套接字描述符也要使用完後關閉該套接字。

       unp第4.9節,這樣描述close函數“通常的Unixclose函數也用來關閉套接字,並終止TCP連接。”這給了我一個錯覺,似乎udp不用調用close來關閉套接字描述符。

       linuxman這麼解釋close函數

DESCRIPTION
       close()  closes  a file descriptor, so that it no longer refers to any file and may be
       reused.  Any record locks (see fcntl(2)) held on the file it was associated with,  and
       owned  by the process, are removed (regardless of the file descriptor that was used to
       obtain the lock).

close操作會關閉文件描述符,並可以被重用,且該進程中與之相關的記錄鎖將被移除。這樣在調用了close之後。這樣系統打開的文件描述符,不會超出進程能夠打開最大文件描述符的閥值。

       我們知道,系統有一個文件描述符的最大值(可以使用cat /proc/sys/fs/file-max來查看)。而單個進程能夠打開的描述符也有個最大值(可以使用ulimit –n來查看)。

       對於以下測試代碼,其系統環境中單個進程允許打開的最大描述符個數爲1024。

#include <sys/types.h>          
#include <sys/socket.h>
#include <stdio.h>

int main()
{
        int count=1,fd;
        while(1)
        {
                fd = socket(PF_INET,SOCK_DGRAM,0);
                if(fd == -1)
                {
                        printf("socket create error!\n");
                        perror("CREATE:");
                        exit(-1);
                }
                printf("%d ",count);
                count++;
        }
        return 0;
}

    當輸出到1021時,程序退出(0,1,2,已被自動打開,並分別被shell與標準輸入、標準輸出、標準出錯相關聯)。這也就是說,當某個進程已經打開了其能夠打開的文件描述符的最大值,那麼再一次打開新的文件描述符將操作失敗,並返回-1。至於之前爲什麼項目裏,出現的現象是阻塞於創建socket的調用,就有待研究了。

本人享有博客文章的版權,轉載請標明出處http://blog.csdn.net/baidu20008

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章