linux高级I/O函数(1)——dup和dup2

1、文件描述符

在学习高级I/O函数时,我们需要对linux的文件描述符,文件描述符表等等有一定了解,在linux系统中,一切皆文件,
每一个进程都在PCB维护一个文件描述符表,文件描述符是指向一个进程打开的文件,在文件描述符表中,0、1、2三个文件描述符分别被标准输入(STDIN)、标准输出(STDOUT)、标准错误输出(STDERR)占用,所以我们自己使用的文件描述符都是从3号开始的(会自动寻找到最小的还没用的,或是已经关闭的文件描述符使用)
文件描述符是一个整数值
文件描述符详细—传送门

2、dup和dup2函数

用于复制文件描述符,将某个文件描述符(比如标准输出)重定向到一个文件,又或者是一个网络连接(套接字)。
dup函数创建一个新的文件描述符,返回新的文件描述符,创建的新的文件描述符和原有的文件描述符(也就是传入的参数fd,指向相同的文件、管道或是网络连接),同时要注意的是,dup返回的文件描述符总是取系统当前可用的最小整数值。
dup2和dup函数类似,只不过返回的文件描述符的值要小于给的第二个参数。
两个函数调用失败都返回-1,设置errno

#include <unistd.h>
int dup(int fd)
int dup2(int fd_one , int fd_two)
3、代码示例

我希望弄这么一个程序,服务器和客户端之间进行数据传输,本来应该是通过套接字进行数据传输,我在服务器端将accept到的客户端套接字socket指向标准输出,那么在服务器打印(printf)的数据应该就会传送到客户端,客户端在读取出来显示到标准输出

server:


  1 #include <sys/socket.h>
  2 #include <netinet/in.h>
  3 #include <arpa/inet.h>
  4 #include <stdio.h>
  5 #include <unistd.h>
  6 #include <stdlib.h>
  7 #include <errno.h>
  8 #include <string.h>
  9 
 10 #define PORT 10086
 //若main函数没有参数,这里记得给void,反正我的虚拟机这个位置不报错但是程序执行就会有问题
 11 int main(void)
 12 {
 13         int lfd , cfd;
 14         struct sockaddr_in address;
 15         bzero( &address , sizeof(address) );
 16         address.sin_family = AF_INET;
 17         address.sin_addr.s_addr = htonl(INADDR_ANY);
 18         address.sin_port = htons(PORT);
 19 
 20         lfd = socket(AF_INET, SOCK_STREAM, 0);
 21         if (lfd < 0) {
 22                 printf("socket() error\n");
 23                 return -1;
 24         }
 25         if (bind(lfd, (struct sockaddr*)&address, sizeof(address)) < 0) {
 26                 printf("bind() error\n");
 27                 return -1;
 28         }
 29         listen(lfd, 5);
 30         printf("server is ready for client\n");
 31 
 32         struct sockaddr_in addr_client;
 33         bzero(&addr_client, sizeof(addr_client));
 34         socklen_t client_len = sizeof(addr_client);
 35 
 36         cfd = accept(lfd, (struct sockaddr*)&addr_client, &client_len);
 37         if (cfd < 0) {
 38                 printf("accept() error\n");
 39                                                                                                                                 
 40         }
 41         printf("client is connect....")
 42         else
 43         {
 44                 close(STDOUT_FILENO);
 45                 dup(cfd); //自动赋值到上面close掉的文件描述符的位置,因为是从小开始找到第一个可用的文件描述符
 46                 printf("hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh");
 47                 close(cfd);                                                                                                     
 48         }
 49         close(lfd);
 50         return 0;
 51 
 52 }

client:

  1 #include <stdio.h>
  2 #include <unistd.h>
  3 #include <string.h>
  4 #include <sys/socket.h>
  5 #include <arpa/inet.h>
  6 
  7 
  8 #define SERV_IP "127.0.0.1"
  9 #define SERV_PORT 10086
 10 
 11 int main(void)
 12 {
 13         int sfd, len;
 14         char buf[BUFSIZ];
 15         struct sockaddr_in serv_addr;
 16         sfd = socket(AF_INET, SOCK_STREAM, 0);
 17 
 18         bzero(&serv_addr, sizeof(serv_addr));
 19         serv_addr.sin_family = AF_INET;
 20 
 21         inet_pton(AF_INET, SERV_IP, &serv_addr.sin_addr.s_addr);
 22 
 23         serv_addr.sin_port = htons(SERV_PORT);
 24 
 25 
 26         connect(sfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr));
 27         len = read(sfd,buf,sizeof(buf));
 28         write(STDOUT_FILENO , buf , len);
 29         while(1);
 30 }

4、测试

当客户端连接上后,就会将hhhhhhhhhhh…显示在屏幕上了

发布了46 篇原创文章 · 获赞 13 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_42718004/article/details/90667182