zoukankan      html  css  js  c++  java
  • server.c客户端服务器 余姗姗

    09计应一班   余姗


    /* server.c */

    #include          /* 包含标准函数库中输入输出函数的头文件 */

    #include         /* 包含标准库函数的头文件 */

    #include         /* 包含字符数组函数定义的头文件 */

    #include     /* IPv4和IPv6的地址格式定义在netinet/in.h中 */

    #include "wrap.h"          /* 系统函数加上错误处理代码包装成新的函数的头文件 */

     

    #define MAXLINE 80/* MAXLINE为80*/

     

    #define SERV_PORT 8000/* 宏定义一个变量SERV_PORT为8000*/

     

    int main(int argc, char **argv)/*主函数 */

    {

           int i, maxi, maxfd, listenfd, connfd, sockfd;/* 定义整型变量i, maxi, maxfd, listenfd, connfd, sockfd */

     

           int nready, client[FD_SETSIZE];/* 定义整型变量nready、整型数组client[FD_SETSIZE]*/

     

           ssize_t n;/*  定义ssize_t类型的n*/

     

           fd_set rset, allset;/* 定义fd_set类型的rset,、allset*/

     

           char buf[MAXLINE];/*定义字符数组 buf[MAXLINE]*/

     

           char str[INET_ADDRSTRLEN];/*定义字符数组str[INET_ADDRSTRLEN]*/

           socklen_t cliaddr_len;/* 定义socklen_t类型的cliaddr_len*/

     

           struct sockaddr_in       cliaddr, servaddr;/*定义两个struct sockaddr_in类型cliaddr、servaddr变量 */

     

           listenfd = Socket(AF_INET, SOCK_STREAM, 0);/* 调用Socket函数还回套接字描述符赋值给listenfd */

     

           bzero(&servaddr, sizeof(servaddr));/* 将servaddr清0 */

     

           servaddr.sin_family      = AF_INET;/* 设置地址类型为AF_INE*/

     

           servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/* 把主机IP 转换为网络字节序赋值给servaddr.sin_addr.s_addr */

     

           servaddr.sin_port        = htons(SERV_PORT);/* 把主机端口号转换为网络字节序赋值给servaddr.sin_port */

     

           Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));/* 绑定一个固定的网络地址和端口号也就是将参数sockfd和servaddr绑定在一起,参数addrlen指定结构体的长度*/

     

           Listen(listenfd, 20);/* listen()声明listenfd处于监听状态,且最多允许有20个客户端处于连接待状态 */

     

           maxfd = listenfd;              /* 把listenfd赋值给maxfd,此时listenfd是最大的*/

           maxi = -1;                     /* 给maxi赋值*/

     

           for (i = 0; i < FD_SETSIZE; i++)/* for循环FD_SETSIZE=1024次*/

                  client[i] = -1;       /* -1 表示可以利用*/

     

           FD_ZERO(&allset);/* 把所有文件描述符集清0*/

     

           FD_SET(listenfd, &allset);/* 把listenfd存放到文件描述符集合allset中*/

     

           for ( ; ; ) /* for 语句死循环 */

            {

                  rset = allset;       /* 把文件描述符集合allset里的描述符赋值给rset*/

                  nready = select(maxfd+1, &rset, NULL, NULL, NULL);/* 调用select还回rset有效的文件描述符的个数给nready*/

     

                  if (nready < 0)/* if条件语句*/

     

                         perr_exit("select error");/*如果nready < 0,调用 perr_exit输出错误信息并退出*/

     

                  if (FD_ISSET(listenfd, &rset)) /*条件调用FD_ISSET函数确认listenfd在 rset*/

                         {

               cliaddr_len = sizeof(cliaddr);/* 把cliaddr的长度赋值给cliaddr_len */

     

                         connfd = Accept(listenfd, (struct sockaddr *)&cliaddr, &cliaddr_len);/* 调用accept()接受连接,accept()返回时传出新的套接字描述符(客户端地址和端口号)给connfd*/

     

                         printf("received from %s at PORT %d ",

                                inet_ntop(AF_INET, &cliaddr.sin_addr, str, sizeof(str)),ntohs(cliaddr.sin_port));/*输出 received from IP at PORT 端口号*/

     

                         for (i = 0; i < FD_SETSIZE; i++)/* for 循环从0到1023*/

     

                                if (client[i] < 0) /*条件client[i] < 0表示client[i]可以利用*/

                                    {

                                       client[i] = connfd; /*把 connfd保存在client[i]里面*/

                                       break;/* 跳出此for语句整个循环*/

                                }

                         if (i == FD_SETSIZE) /*条件i == FD_SETSIZE表示已经出错*/

                           {

                                fputs("too many clients ", stderr);/* 输出错误信息到 stderr*/

                                exit(1);/* 退出*/

                         }

     

                         FD_SET(connfd, &allset);       /* 把connfd放到文件描述符集合allset里 面*/

     

                         if (connfd > maxfd)/*如果条件connfd > maxfd */

     

                                maxfd = connfd; /* 把connfd赋值给 maxfd 保证已有套接字描述符中 maxfd 值是最大的,在select 中要用到maxfd*/

     

                         if (i > maxi)/* 如果条件i > maxi */

     

                                maxi = i;       /*maxi 表示已用client[i]的最大索引*/

     

                         if (--nready == 0)/* if条件nready自减1等于0 */

                                continue;      

                  }

     

                  for (i = 0; i <= maxi; i++)       /* for 检查 0到maxi的client[i]里保存的套接字描述符*/

                         {

    if ( (sockfd = client[i]) < 0)/* if条件语句,条件client[i]) < 0表示没保存来自client 的套接字描述符*/

     

                                continue;/* 继续检测*/

                         if (FD_ISSET(sockfd, &rset)) /* 确认sockfd有没在rset里,如果在,执行下面的语句 */

                                  {

                                if ( (n = Read(sockfd, buf, MAXLINE)) == 0)  /* 条件表示客户端关掉了连接 */

                                     {

                                       /* connection closed by client */

     

                                       Close(sockfd);/* 关掉连接*/

     

                                       FD_CLR(sockfd, &allset);/*调用 FD_CLR把此sockfd从allset清除*/

                                       client[i] = -1;/* 使保存此sockfd的client[i]有效空闲*/

                                } else { /* if条件语句  else条件表示读到字节数n>0 */

     

                                       int j;/* 定义整形变量j*/

     

                                       for (j = 0; j < n; j++)/* for 循环从0到读到的字节n*/

     

                                              buf[j] = toupper(buf[j]);/* 把放到buf里的字符转换成大写*/

                                       Write(sockfd, buf, n);/* 调用Write函数写回buf*/

                                }

     

                                if (--nready == 0)/* 条件nready自减1等于0 */

     

                                       break;      

                         }

                  }

           }

    }

    执行结果如下:

    [root@localhost opt]# ./server

    Accepting connections ...

    received from 127.0.0.1 at PORT 50390

    received from 127.0.0.1 at PORT 50390

    received from 127.0.0.1 at PORT 50390

     

     

    [root@localhost opt]# netstat -apn|grep 8000

    tcp        0      0 0.0.0.0:8000                0.0.0.0:*                   LISTEN      4012/server

     

    [root@localhost opt]# ./client

    ajfdsakgworfwrpjhfewhfjsncoiwdhksnxciowfionc

    AJFDSAKGWORFWRPJHFEWHFJSNCOIWDHKSNXCIOWFIONC

    ncxhwoiefncsdjkuieckdsajidejnc

    NCXHWOIEFNCSDJKUIECKDSAJIDEJNC

    ndewanfjkawfsjfiowfmniwamcijfi

    NDEWANFJKAWFSJFIOWFMNIWAMCIJFI

     

     

    /*服务器端负责接受客户端的数据请求,把对一个客户端的数据转发给每个与服务器建立链接的客户端*/

    <script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
    阅读(305) | 评论(0) | 转发(0) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    CSS大杂烩(1)
    菜鸟快飞之JavaScript函数
    mysqldump主要参数分析
    PXC原理分析
    MHA原理分析
    android数据存储之外部存储(External Storage)
    JsonWriter使用
    基于asp.net mvc的近乎产品开发培训课程(第二讲)
    基于asp.net mvc的近乎产品开发培训课程(第一讲)
    MVC的注意事项及开发技巧
  • 原文地址:https://www.cnblogs.com/ztguang/p/12647532.html
Copyright © 2011-2022 走看看