zoukankan      html  css  js  c++  java
  • Linux基础——通过select实现简单的服务器与客户端

    在这里,我们还是需要一个管道,只不过,我们只需这一个管道,即可知道,客户端有哪些上线、对话、下线等。

    服务器端的实现代码如下:

      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include <sys/stat.h>
      5 #include <sys/types.h>
      6 #include <fcntl.h>
      7 #include <sys/time.h>
      8 #include <sys/select.h>
      9 #include <errno.h>
     10 #define ON 1
     11 #define OFF 0
     12 int errno;
     13 typedef struct tag
     14 {
     15     int id;
     16     int fd;
     17     int type;
     18 }NODE;
     19 int main(int argc, const char *argv[])
     20 {
     21     if(mkfifo(argv[1], 0666) == -1)
     22     {
     23         printf("创建管道失败!!
    ");
     24         exit(1);
     25     }
     26     
     27     int fd;
     28     fd = open(argv[1], O_RDONLY);
     29     if(fd == -1)
     30     {
     31         printf("open error!!
    ");
     32         exit(1);
     33     }
     34     NODE list[1024];
     35     int i;
     36     for(i = 0; i< 1024; i ++)
     37     {
     38         list[i].id = 0;
     39         list[i].type = OFF;
     40         list[i].fd = 0;
     41     }
     42     fd_set readset, ready;
     43     FD_ZERO(&readset);
     44     FD_ZERO(&ready);
     45     FD_SET(fd, &readset);
     46     struct timeval tm;
     47     char buf[128];
     48     int ret;
     49     while(1)
     50     {
     51         ready = readset;
     52         tm.tv_sec = 0;
     53         tm.tv_usec = 1000;
     54         ret = select(fd + 1, &ready, NULL, NULL, &tm);
     55         if(ret == 0)
     56             continue;
     57         else if(ret == -1)
     58         {
     59             if(errno == EINTR)
     60                 continue;
     61             break;
     62         }
     63         else
     64         {
     65             memset(buf, 0, 128);
     66             read(fd, buf, 128);
     67             if(strncmp(buf, "on", 2) == 0)
     68             {
     69                 int sfd;
     70                 char name[128];
     71                 memset(name, 0, 128);
     72                 sscanf(buf + 3, "%d", &sfd);
     73                 printf(" %d is on !!
    ", sfd);
     74                 sprintf(name, "%d.fifo", sfd);
     75                 int index;
     76                 for(index = 0; index < 1024; index ++)
     77                 {
     78                     if(list[index].type == OFF)
     79                     {
     80                         list[index].id = sfd;
     81                         list[index].fd = open(name, O_WRONLY);
     82                         list[index].type = ON;
     83                         break;
     84                     }
     85                 }
     86             }
     87             else if(strncmp(buf, "off", 3) == 0)
     88             {
     89                 int sfd;
     90                 sscanf(buf + 4, "%d", &sfd);
     91                 printf("%d is off !!
    ", sfd);
     92                 int index;
     93                 for(index = 0; index <1024; index ++)
     94                 {
     95                     if(list[index].id == sfd)
     96                     {
     97                         close(list[index].fd);
     98                         list[index].id = 0;
     99                         list[index].type = OFF;
    100                         break;
    101                     }
    102                 }
    103             }
    104             else
    105             {
    106                 int sfd;
    107                 sscanf(buf + 5, "%d", &sfd);
    108                 int index;
    109                 for(index = 0; index < 1024; index ++)
    110                 {
    111                     if(list[index].type == ON && list[index].id != sfd)
    112                         write(list[index].fd, buf, strlen(buf));
    113                 }
    114             }
    115         }
    116     }
    117     close(fd);
    118     unlink(argv[1]);
    119     return 0;
    120 }
    View Code

    在这里,当ret = -1时,我们需要判断errno是否由信号中断引起的,如果是由于人为的退出,那么程序将退出,

    如果是由于信号中断,程序将再次连接信号,等待数据。

    客户端的实现代码如下:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <string.h>
     4 #include <sys/stat.h>
     5 #include <sys/time.h>
     6 #include <sys/types.h>
     7 #include <sys/select.h>
     8 #include <fcntl.h>
     9 int main(int argc, const char *argv[])
    10 {
    11     char name[128];
    12     memset(name, 0, 128);
    13     sprintf(name, "%d.fifo", getpid());
    14     if(mkfifo(name, 0666) == -1)
    15     {
    16         printf("创建管道失败!!
    ");
    17         exit(1);
    18     }
    19     int fd;
    20     fd = open(argv[1], O_WRONLY);
    21     if(fd == -1)
    22     {
    23         printf("open error!!
    ");
    24         exit(1);
    25     }
    26     char buf[128];
    27     memset(buf, 0, 128);
    28     sprintf(buf,"on %d
    ",getpid());
    29     write(fd, buf, strlen(name));
    30     int sfd;
    31     sfd = open(name, O_RDONLY);
    32     if(sfd == -1)
    33     {
    34         printf("open error!!
    ");
    35         exit(1);
    36     }
    37     if(fork() == 0)
    38     {
    39         if(fork() == 0)
    40         {
    41             close(fd);
    42             while(memset(buf, 0, 128), read(sfd, buf, 128))
    43                 printf(" >> %s
    ", buf);
    44             close(sfd);
    45             exit(1);
    46         }
    47         exit(1);
    48     }
    49     wait(NULL);
    50     close(sfd);
    51     while(memset(buf, 0, 128), fgets(buf, 128, stdin) != NULL)
    52     {
    53         char msg[128];
    54         memset(msg, 0, 128);
    55         sprintf(msg, "from %d: %s",getpid(), buf);
    56         write(fd, msg, strlen(msg));
    57     }
    58     memset(buf, 0, 128);
    59     sprintf(buf, "off %d
    ", getpid());
    60     write(fd, buf, strlen(buf));
    61     close(fd);
    62     unlink(name);
    63     return 0;
    64 }
    View Code
  • 相关阅读:
    PDOStatement::closeCursor
    PDOStatement::bindValue
    oracle drop table recyclebin恢复
    mysql基准测试工具tpcc-mysql安装、使用、结果解读
    MySQL字符集 GBK、GB2312、UTF8区别 解决 MYSQL中文乱码问题 收藏 MySQL中涉及的几个字符集
    [MySQL FAQ]系列 — EXPLAIN结果中哪些信息要引起关注
    [MySQL优化案例]系列 — 优化InnoDB表BLOB列的存储效率
    数据库专业词语
    老叶观点:MySQL开发规范之我见
    [MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键
  • 原文地址:https://www.cnblogs.com/gjn135120/p/4009301.html
Copyright © 2011-2022 走看看