Linux编程--文件描述符fd

本文深入解析Linux中文件描述符(FD)的工作原理,包括其在内核中的数组表示、分配原则,以及与标准输入输出的关系。同时,介绍了如何查询系统和进程级别的FD数量限制与使用情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

    linux中, 每一个进程在内核中,都对应有一个“打开文件”数组,存放指向文件对象的指针,而 fd 是这个数组的下标

    我们对文件进行操作时,系统调用,将fd传入内核,内核通过fd找到文件,对文件进行操作。

    既然是数组下标,fd的类型为int, < 0 为非法值, >=0 为合法值。在linux中,一个进程默认可以打开的文件数为1024个,fd的范围为0~1023。可以通过设置,改变最大值。

    在linux中,值为0、1、2的fd,分别代表标准输入、标准输出、标准错误输出。在上一篇文章中,使用重定向 2>/dev/null 就是把标准错误输出重定向到位桶中去,不显示出来。因为 0 1 2已经被linux使用了,通常在程序中打开的fd,是从3开始的。但我们在判断一个fd是否合法时,依然要使用>=0的判断标准

    fd的分配原则,是从小到大,找到第一个不用的进行分配。

    除了open之外, socket编程的socket()/accept()等函数,也会返回一个fd值。

 

    1)Linux系统下,所有进程允许打开的最大fd数量。查询语句:

        /proc/sys/fs/file-max
    2)Linux系统下,所有进程已经打开的fd数量及允许的最大数量。查询语句:

        /proc/sys/fs/file-nr
    3)单个进程允许打开的最大fd数量.查询语句:

        ulimit -n
    4)单个进程(例如进程id为5454)已经打开的fd.查询语句:

        ls -l /proc/5454/fd/
 

C语言是一种常用的编程语言,也是Linux网络编程中最常用的编程语言之一。在C语言中,可以使用Socket API进行网络编程。以下是一个简单的C语言程序,演示了如何使用Socket API实现一个简单的客户端/服务器模型: 服务器端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #define PORT 8888 #define MAXLINE 1024 int main() { int server_fd, conn_fd; struct sockaddr_in server_addr, client_addr; char buffer[MAXLINE]; int n; // 创建socket if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } // 初始化服务器地址 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY); server_addr.sin_port = htons(PORT); // 绑定socket和地址 if (bind(server_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("bind"); exit(1); } // 启动监听 if (listen(server_fd, 5) == -1) { perror("listen"); exit(1); } printf("Server is listening on port %d...\n", PORT); // 接收客户端连接 socklen_t client_len = sizeof(client_addr); if ((conn_fd = accept(server_fd, (struct sockaddr *)&client_addr, &client_len)) == -1) { perror("accept"); exit(1); } printf("Client connected.\n"); // 接收客户端消息并回传 while (1) { memset(buffer, 0, sizeof(buffer)); if ((n = read(conn_fd, buffer, MAXLINE)) == -1) { perror("read"); exit(1); } else if (n == 0) { printf("Client disconnected.\n"); break; } printf("Received message from client: %s", buffer); if (write(conn_fd, buffer, n) == -1) { perror("write"); exit(1); } } close(conn_fd); close(server_fd); return 0; } ``` 客户端代码: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #define PORT 8888 #define MAXLINE 1024 int main() { int client_fd; struct sockaddr_in server_addr; char buffer[MAXLINE]; int n; // 创建socket if ((client_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } // 初始化服务器地址 memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); server_addr.sin_port = htons(PORT); // 连接服务器 if (connect(client_fd, (struct sockaddr *)&server_addr, sizeof(server_addr)) == -1) { perror("connect"); exit(1); } printf("Connected to server.\n"); // 发送消息给服务器 while (1) { printf("Input message to send: "); fgets(buffer, MAXLINE, stdin); if (write(client_fd, buffer, strlen(buffer)) == -1) { perror("write"); exit(1); } memset(buffer, 0, sizeof(buffer)); if ((n = read(client_fd, buffer, MAXLINE)) == -1) { perror("read"); exit(1); } else if (n == 0) { printf("Server disconnected.\n"); break; } printf("Received message from server: %s", buffer); } close(client_fd); return 0; } ``` 以上程序演示了一个简单的客户端/服务器模型,服务器可以接收客户端发送的消息并回传,客户端可以向服务器发送消息并接收回传。这只是一个简单的示例程序,Linux网络编程还涉及到很多高级的知识,需要深入学习和实践。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值