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

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV是一个开源的计算机视觉库,它可以用于图像处理、计算机视觉和机器学习等领域。在使用OpenCV调用UDP网络摄像头时,可以通过以下步骤实现: 1. 在CMakeList.txt文件中添加UDP库的链接。 2. 在代码中使用OpenCV库获取UDP网络摄像头的视频流。 3. 将获取到的视频流通过UDP协议传送至服务器端。 具体实现步骤可以参考以下代码: ``` #include <opencv2/opencv.hpp> #include <iostream> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> using namespace cv; using namespace std; int main(int argc, char** argv) { // 创建UDP套接字 int sockfd = socket(AF_INET, SOCK_DGRAM, 0); if (sockfd < 0) { perror("socket"); return -1; } // 设置服务器地址 struct sockaddr_in servaddr; memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(8888); servaddr.sin_addr.s_addr = inet_addr("192.168.1.100"); // 打开摄像头 VideoCapture cap(0); if (!cap.isOpened()) { cerr << "Failed to open camera." << endl; return -1; } // 循环获取视频流并发送至服务器 Mat frame; while (true) { cap >> frame; if (frame.empty()) { cerr << "Failed to capture frame." << endl; break; } // 将视频流转换为字符串并发送至服务器 vector<uchar> buf; imencode(".jpg", frame, buf); sendto(sockfd, buf.data(), buf.size(), 0, (struct sockaddr*)&servaddr, sizeof(servaddr)); } // 关闭套接字和摄像头 close(sockfd); cap.release(); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值