高级编程之网络编程(三)

来源:互联网 发布:破解rar密码软件 编辑:程序博客网 时间:2024/06/06 04:05

IO 模型

1、阻塞模型
  fifo  pipe   read  fgetc fgets  fread recv recvfrom

  以上获取数据的函数默认都是阻塞方式接收数据。

2、非阻塞模型

 2.1 在开始阶段的open函数部分调整 。

  open("./fifo",O_RDONLY|O_NONBLOCK);
  函数  open  read ....都不会阻塞。

 2.2 在文件打开之后操作过程中调整。
  fcntl()===>用法
  int flag  ;
  flag = fcntl(fd,F_GETFL,0);///获取当前fd文件的属性。
  flag = flag | O_NONBLOCK;  ///修改当前属性为非阻塞方式。
  fcntl(fd,F_SETFL,flag);    ///设置当前fd文件的属性为flag

3、多路复用模型

 3.1  简单循环服务器

   由服务器端为每个新链接创建一次链接过程并获取数据
   之后关闭链接,等待下一个新链接。

   while(1)
   {
    newfd = accept()
    ....read/wait
    close(newfd);
   }

   适用范围:数据通信过程短,发送数据少,实时时间短。
   缺陷:每次客户端发送完毕下次发送需要重链。

 3.2  fork循环服务器

   服务器为客户端的链接每次新建一个子进程用来保持通信
   父进程继续循环检测,如果还有新链接则继续fork子进程。

   while(1)
   {
    newfd = accpet();
    if(newfd > 0)
    {
     count++;
     pid= fork();
     if(pid == 0)
     {
      deal_recv();
      exit(0);
        }
    }
    else
   {
    perror(accept);
    reutrn -1;
   }
   if(count >40) break;
   }

   for(i=0;i<40;i++)
  {
   wait(NULL);
  }


  缺陷:1 、有僵尸进程出现
     2、客户端退出服务器无法获取。
     3、资源消耗大
     4、子进程退出不方便回收
  
  适用范围: 客户端个数少
       客户端能正常退出并有一定时间范围。


  3、select循环服务器 ====>通过select 函数完成IO的多路复用。
    
   头文件: sys/select.h  sys/time.h  sys/types.h unistd.h
  
     函数:int select(int nfds, fd_set *readfds, fd_set *writefds,
                     fd_set *exceptfds, struct timeval *timeout);

     功能:通过该函数可以动态检测当前指定的文件描述符集合中有
        数据变化的文件描述符,并将其他描述符删除,只保留当
     前有数据流的描述符。同时该函数具有阻塞等待功能。

     参数:nfds   当前进程打开的最大描述符的边界值。
        readfds  读操作的描述符集合
     writefds 写操作的描述符集合
     exectpfds 异常描述符集合。如果为NULL表示不对异常描述符处理。
       timeout  超时设置,如果该值为NULL表示一直阻塞检测。
   返回值:成功 0
     失败 -1;

void FD_CLR(int fd, fd_set *set);
功能:将描述符集合set中的fd描述符删除。
    
int  FD_ISSET(int fd, fd_set *set);
功能:判断fd描述符是否在set集合中。如果是则返回真,否则假。
    
void FD_SET(int fd, fd_set *set);
功能:将fd描述符添加到set集合中。
     
void FD_ZERO(fd_set *set);
功能:将set集合中所有描述符删除。


练习:用select 函数完成一个并发文件服务器,可以接收客户端
   发送的文件并以客户端IP形式存储到本地服务器。

 

 

 

 

 

0 0
原创粉丝点击