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
  • 相关阅读:
    C# 不用添加WebService引用,调用WebService方法
    贪心 & 动态规划
    trie树 讲解 (转载)
    poj 2151 Check the difficulty of problems (检查问题的难度)
    poj 2513 Colored Sticks 彩色棒
    poj1442 Black Box 栈和优先队列
    啦啦啦
    poj 1265 Area(pick定理)
    poj 2418 Hardwood Species (trie树)
    poj 1836 Alignment 排队
  • 原文地址:https://www.cnblogs.com/gjn135120/p/4009301.html
Copyright © 2011-2022 走看看