ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

数据中继poll模型

2022-08-01 08:33:24  阅读:155  来源: 互联网

标签:中继 pfd 模型 STATE fsm fd1 state fd2 poll


数据中继poll模型

示例:relay_poll.c

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <poll.h>

#define FILE1 "/dev/tty10"  //终端
#define FILE2 "/dev/tty11"
#define BUFFSIZE 1024

enum fsmstate  //状态机状态
{
  STATE_R,
  STATE_W,
  STATE_AUTO,
  STATE_EX,
  STATE_T
};

struct fsm_st  //状态机数据结构
{
  enum fsmstate state;
  int sfd;
  int dfd;
  int lenth;
  int pos;
  char *err;
  char buff[BUFFSIZE];
};

static void fsm_driver(struct fsm_st *fsm)  //状态机
{
  int ret;

  switch(fsm->state)  //状态切换及处理
  {
    case STATE_R: //读状态
      fsm->lenth = read(fsm->sfd,fsm->buff,BUFFSIZE);
      if(fsm->lenth<0)
      {
        if(errno == EAGAIN)
          fsm->state = STATE_R;
        else
        {
          fsm->err = "read";
          fsm->state = STATE_EX;
        }
      }
      else if(fsm->lenth == 0)
        fsm->state = STATE_T;
      else
      {
        fsm->pos =0;
        fsm->state = STATE_W;
      }
      break;
    case STATE_W: //写状态
      ret = write(fsm->dfd,fsm->buff + fsm->pos,fsm->lenth);
      if(ret <0)
      {
        if(errno == EAGAIN)
          fsm->state = STATE_W;
        else
        {
          fsm->err = "write";
          fsm->state = STATE_EX;
        }
      }
      else
      {
        fsm->pos +=ret;
        fsm->lenth -=ret;
        if(fsm->lenth ==0)
          fsm->state = STATE_R;
        fsm->state = STATE_W;
      }
      break;
    case STATE_EX: //异常状态
      fprintf(stderr,"%s\n",fsm->err);
      fsm->state = STATE_T;
      break;
    case STATE_T: //完成状态
      break;
    default:
      abort();
      break;
  }
}

static int max(int a,int b)
{
  if(a > b)
    return a;
  return b;
}

static void relay(int fd1, int fd2) 
{
  struct fsm_st fsm12,fsm21;
  int fd1_save,fd2_save;
  struct pollfd pfd[3];   //poll文件集数组

  fd1_save = fcntl(fd1,F_GETFL);
  fsm12.state = STATE_R;
  fsm12.sfd = fd1;
  fsm12.dfd = fd2;

  fd2_save = fcntl(fd2,F_GETFL);
  fsm21.state = STATE_R;
  fsm21.sfd = fd2;
  fsm21.dfd = fd1;

  pfd[0].fd = fd1;  //初始化struct pollfd
  pfd[0].events = 0;

  pfd[1].fd = fd2;
  pfd[1].events = 0;

  while(fsm12.state != STATE_T || fsm21.state != STATE_T)
  {
    if(fsm12.state == STATE_R)
      pfd[0].events |= POLLIN;  //设置监测事件
    if(fsm12.state == STATE_W)
      pfd[1].events |= POLLOUT;
    if(fsm21.state == STATE_R)
      pfd[1].events |= POLLIN;
    if(fsm21.state == STATE_W)
      pfd[0].events |= POLLOUT;

    if(fsm12.state <STATE_AUTO || fsm21.state <STATE_AUTO)
    {
      if(poll(pfd, 2, -1)<0)   //调用poll函数   监测文件集,监测2个文件,阻塞监控
      {
        if(errno == EINTR)
          continue;
        perror("poll()");
        exit(1);
      }
    }

    if( pfd[0].revents&POLLIN || pfd[1].revents&POLLOUT || fsm12.state > STATE_AUTO)  //判断状态启用状态机
      fsm_driver(&fsm12);
    if( pfd[1].revents&POLLIN || pfd[0].revents&POLLOUT || fsm21.state >STATE_AUTO)
      fsm_driver(&fsm21);
  }

  fcntl(fd1,F_SETFL,fd1_save);  //恢复文件属性
  fcntl(fd2,F_SETFL,fd2_save);
}

int main()
{
  int fd1,fd2;

  fd1 = open(FILE1,O_RDWR|O_NONBLOCK); //非阻塞方式打开
  if(fd1 <0)
  {
    perror("open()");
    exit(1);
  }

  fd2 = open(FILE2,O_RDWR|O_NONBLOCK); //非阻塞方式打开
  if(fd2 <0)
  {
    perror("open()");
    exit(1);
  }


  relay(fd1,fd2);

  while(1)
    pause();  //等待

  close(fd1);
  close(fd2);

  exit(0);
}  

标签:中继,pfd,模型,STATE,fsm,fd1,state,fd2,poll
来源: https://www.cnblogs.com/linux-learn/p/16538868.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有