//./client 192.168.91.11 /etc/hosts int main(int argc, const char *argv[]) { int len; struct fsm_st fsm; struct sigaction sa; struct sockaddr_in saddr; if (argc!=3) { printf("usgae:./client 192.168.91.11 /etc/httpd/conf/httpd.conf\n"); exit(-1); } fsm.client_sd = socket(AF_INET, SOCK_DGRAM, 0/*IPPROTO_UDP*/); if(fsm.client_sd < 0) { perror("socket()"); exit(-1); } fsm.state = STATE_SEND; memset(&fsm.path_buf, 0x00, sizeof(fsm.path_buf)); fsm.path_buf.mtype = MSG_PATH; strcpy(fsm.path_buf.path, argv[1]); saddr.sin_family = AF_INET; saddr.sin_port = htons(atoi(RCVPORT)); if(inet_pton(AF_INET, argv[1], &saddr.sin_addr)!=1) { perror("inet_pton()"); exit(-1); } fsm.server_addr = saddr; strcpy(fsm.path_buf.path, argv[2]); while (1) { fsm_driver(&fsm); } exit(0); }
int main(int argc, const char *argv[]){ struct fsm_st fsm; key_t key; int msgid; if (argc<2) { printf("usgae:./client /etc/httpd/conf/httpd.conf\n"); exit(-1); } key = ftok(KEYPATH, KEYPROJ); if(key < 0){ perror("ftok():"); exit(-1); } msgid = msgget(key,0); if(msgid < 0){ perror("msgget():"); exit(-1); } fsm.state = STATE_SEND; fsm.msgid = msgid; fsm.path_buf.mtype = MSG_PATH; strcpy(fsm.path_buf.path, argv[1]); while (1) { fsm_driver(&fsm); } exit(0); }
static void rely(int sfd, int dfd){ int fd; struct fsm_st fs; fs.state = STATE_R; fs.sfd = sfd; fs.dfd = dfd; while(1){ fsm_driver(&fs); } }
/* 推动状态机 */ static void relay(int fd1,int fd2) { int fd1_save,fd2_save; // 因为是读 tty1 写 tty2;读 tty2 写 tty1,所以这里的两个状态机直接取名为 fsm12 和 fsm21 struct fsm_st fsm12,fsm21; fd1_save = fcntl(fd1,F_GETFL); // 使用状态机操作 IO 一般都采用非阻塞的形式,避免状态机被阻塞 fcntl(fd1,F_SETFL,fd1_save|O_NONBLOCK); fd2_save = fcntl(fd2,F_GETFL); fcntl(fd2,F_SETFL,fd2_save|O_NONBLOCK); // 在启动状态机之前将状态机推向 读态 fsm12.state = STATE_R; // 设置状态机中读写的来源和目标,这样状态机的读写接口就统一了。在状态机里面不用管到底是 读tty1 写tty2 还是 读tty2 写tty1 了,它只需要知道是 读src 写des 就可以了。 fsm12.sfd = fd1; fsm12.dfd = fd2; // 同上 fsm21.state = STATE_R; fsm21.sfd = fd2; fsm21.dfd = fd1; // 开始推状态机,只要不是 T态 就一直推 while(fsm12.state != STATE_T || fsm21.state != STATE_T) { // 调用状态机驱动函数,状态机开始工作 fsm_driver(&fsm12); fsm_driver(&fsm21); } fcntl(fd1,F_SETFL,fd1_save); fcntl(fd2,F_SETFL,fd2_save); }
int main(void){ struct fsm_st fsm; key_t key; int msgid; key = ftok(KEYPATH, KEYPROJ); if(key < 0){ perror("ftok():"); exit(-1); } msgid = msgget(key, IPC_CREAT|0666); if(msgid < 0){ perror("msgget():"); exit(-1); } fsm.state = STATE_RCV; fsm.msgid = msgid; while (1) { fsm_driver(&fsm); } exit(0); }
static void relay(FD_ST* p1 , FD_ST* p2) { int num; struct fsm_st fsm12,fsm21; int epfd; struct epoll_event ev; epfd = epoll_create(1);//传参正整数即可,无意义 if (epfd < 0) { perror("epoll_create():"); exit(1); } fsm12.state = STATE_R; fsm12.sfd = p1->fd; fsm12.dfd = p2->fd; fsm21.state = STATE_R; fsm21.sfd = p2->fd; fsm21.dfd = p1->fd; ev.events = 0; ev.data.ptr = p1; epoll_ctl(epfd, EPOLL_CTL_ADD, p1->fd, &ev); ev.events = 0; ev.data.ptr = p2; epoll_ctl(epfd, EPOLL_CTL_ADD, p2->fd, &ev); while(fsm12.state != STATE_T || fsm21.state != STATE_T) { /*布置监视任务*/ printf("布置监视任务\n"); ev.data.ptr = p1; ev.events = 0; if(fsm12.state == STATE_R){ printf("fsm12 state_r\n"); ev.events |= EPOLLIN; } if(fsm21.state == STATE_W){ printf("fsm21 state_w\n"); ev.events |= EPOLLOUT; } epoll_ctl(epfd, EPOLL_CTL_MOD, p1->fd, &ev); ev.data.ptr = p2; ev.events = 0; if(fsm12.state == STATE_W){ printf("fsm12 state_w\n"); ev.events |= EPOLLOUT; } if(fsm21.state == STATE_R){ printf("fsm21 state_r\n"); ev.events |= EPOLLIN; } epoll_ctl(epfd, EPOLL_CTL_MOD, p2->fd, &ev); /*监视*/ if(fsm12.state < STATE_AUTO || fsm21.state < STATE_AUTO) { while( (num = epoll_wait(epfd, &ev, 1, -1))< 0) { if(errno == EINTR){ continue; } perror("epoll_wait()"); exit(1); } } printf("============= unblock num is %d=============\n", num); /*查看监视结果*/ if( ((FD_ST *)ev.data.ptr)->fd == p1->fd && ev.events & EPOLLIN ||\ ((FD_ST *)ev.data.ptr)->fd == p2->fd && ev.events & EPOLLOUT ||\ fsm12.state > STATE_AUTO ){ fsm_driver(&fsm12, &ev); } if( ((FD_ST *)ev.data.ptr)->fd == p2->fd && ev.events & EPOLLIN ||\ ((FD_ST *)ev.data.ptr)->fd == p1->fd && ev.events & EPOLLOUT ||\ fsm21.state > STATE_AUTO ){ fsm_driver(&fsm21, &ev); } } close(epfd); }
void *thr_relayer(void *p) { int i; fd_set rset,wset; int maxfd=0; while(1) { //布置监视任务 printf("布置监视任务\n"); FD_ZERO(&rset); FD_ZERO(&wset); for(i = 0 ; i < REL_JOBMAX ; i++) { if(rel_job[i] != NULL) { maxfd = (maxfd, max(rel_job[i]->fd1, rel_job[i]->fd2)); if(rel_job[i]->job_state == STATE_RUNNING) { if(rel_job[i]->fsm12.state == STATE_R){ printf("i:%d,fsm12 state_r\n",i); FD_SET(rel_job[i]->fsm12.sfd,&rset); } if(rel_job[i]->fsm12.state == STATE_W){ printf("i:%d,fsm12 state_w\n",i); FD_SET(rel_job[i]->fsm12.dfd,&wset); } if(rel_job[i]->fsm21.state == STATE_R){ printf("i:%d,fsm21 state_r\n",i); FD_SET(rel_job[i]->fsm21.sfd,&rset); } if(rel_job[i]->fsm21.state == STATE_W){ printf("i%d,fsm21 state_w\n",i); FD_SET(rel_job[i]->fsm21.dfd,&wset); } //为了处理无条件Ex->T if(rel_job[i]->fsm12.state > STATE_AUTO){ fsm_driver(&rel_job[i]->fsm12); } if(rel_job[i]->fsm21.state > STATE_AUTO){ fsm_driver(&rel_job[i]->fsm21); } } } } //监视 printf("block max fd %d\n", maxfd); if(select(maxfd+1,&rset,&wset,NULL,NULL)<0) { if(errno == EINTR) continue; perror("select()"); exit(1); } /*查看监视结果*/ printf("unblock\n"); pthread_mutex_lock(&mut_rel_job); for(i = 0 ; i < REL_JOBMAX ; i++) { if(rel_job[i] != NULL) { if(rel_job[i]->job_state == STATE_RUNNING) { if(FD_ISSET(rel_job[i]->fd1,&rset) || FD_ISSET(rel_job[i]->fd2,&wset)){ printf("fsm12\n"); fsm_driver(&rel_job[i]->fsm12); } if(FD_ISSET(rel_job[i]->fd2,&rset) || FD_ISSET(rel_job[i]->fd1,&wset)){ printf("fsm21\n"); fsm_driver(&rel_job[i]->fsm21); } } } } pthread_mutex_unlock(&mut_rel_job); } }
static void relay(int fd1,int fd2) { int num; int fd1_save,fd2_save; struct fsm_st fsm12,fsm21; int epfd; struct epoll_event ev; //struct epoll_event ev_arr[1]; epfd = epoll_create(1);//传参正整数即可,无意义 if (epfd < 0) { perror("epoll_create():"); exit(1); } //使用阻塞IO完全没问题2个状态机不会影响 //因为select获取到文件描述符事件后, //FD_ISET可以准确获取那个fd的什么事件从而确定运行那个状态机 fd1_save = fcntl(fd1,F_GETFL); //fcntl(fd1,F_SETFL,fd1_save|O_NONBLOCK); fd2_save = fcntl(fd2,F_GETFL); //fcntl(fd2,F_SETFL,fd2_save|O_NONBLOCK); fsm12.state = STATE_R; fsm12.sfd = fd1; fsm12.dfd = fd2; fsm21.state = STATE_R; fsm21.sfd = fd2; fsm21.dfd = fd1; ev.events = 0; ev.data.fd = fd1; epoll_ctl(epfd, EPOLL_CTL_ADD, fd1, &ev); ev.events = 0; ev.data.fd = fd2; epoll_ctl(epfd, EPOLL_CTL_ADD, fd2, &ev); while(fsm12.state != STATE_T || fsm21.state != STATE_T) { /*布置监视任务*/ printf("布置监视任务\n"); ev.data.fd = fd1; ev.events = 0; if(fsm12.state == STATE_R){ printf("fsm12 state_r\n"); ev.events |= EPOLLIN; } if(fsm21.state == STATE_W){ printf("fsm21 state_w\n"); ev.events |= EPOLLOUT; } epoll_ctl(epfd, EPOLL_CTL_MOD, fd1, &ev); ev.data.fd = fd2; ev.events = 0; if(fsm12.state == STATE_W){ printf("fsm12 state_w\n"); ev.events |= EPOLLOUT; } if(fsm21.state == STATE_R){ printf("fsm21 state_r\n"); ev.events |= EPOLLIN; } epoll_ctl(epfd, EPOLL_CTL_MOD, fd2, &ev); /*监视*/ if(fsm12.state < STATE_AUTO || fsm21.state < STATE_AUTO) { while( (num = epoll_wait(epfd, &ev, 1, -1))< 0) //while( (num = epoll_wait(epfd, ev_arr, 1, -1))< 0) { if(errno == EINTR){ continue; } perror("epoll_wait()"); exit(1); } } printf("============= unblock num is %d=============\n", num); /*查看监视结果*/ if(ev.data.fd == fd1 && ev.events & EPOLLIN ||\ ev.data.fd == fd2 && ev.events & EPOLLOUT ||\ fsm12.state > STATE_AUTO){ fsm_driver(&fsm12); } if(ev.data.fd == fd2 && ev.events & EPOLLIN ||\ ev.data.fd == fd1 && ev.events & EPOLLOUT ||\ fsm21.state > STATE_AUTO){ fsm_driver(&fsm21); } //if(ev_arr[0].data.fd == fd1 && ev_arr[0].events & EPOLLIN ||\ // ev_arr[0].data.fd == fd2 && ev_arr[0].events & EPOLLOUT ||\ // fsm12.state > STATE_AUTO){ // fsm_driver(&fsm12); //} //if(ev_arr[0].data.fd == fd2 && ev_arr[0].events & EPOLLIN ||\ // ev_arr[0].data.fd == fd1 && ev_arr[0].events & EPOLLOUT ||\ // fsm21.state > STATE_AUTO){ // fsm_driver(&fsm21); //} } fcntl(fd1,F_SETFL,fd1_save); fcntl(fd2,F_SETFL,fd2_save); close(epfd); }