zoukankan      html  css  js  c++  java
  • server select 刘莹

    姓名:刘莹 班级:应用一班 学号:0906041036
    /* server.c */
    #include /*标准函数库中的输入输出函数头文件*/
    #include /* c语言标准库函数头文件*/
    #include /*包含字符串操作的基本函数的头文件*/
    #include /* IPv4和IPv6的地址格式定义在netinet/in.h */
    #include "wrap.h" /* 系统函数加上错误处理代码包装成新的函数的头文件 */

    #define MAXLINE 80
    #define SERV_PORT 8000

    int main(int argc, char **argv) /*主函数 */
    {
    int i, maxi, maxfd, listenfd, connfd, sockfd;
    int nready, client[FD_SETSIZE];
    ssize_t n;
    fd_set rset, allset;
    char buf[MAXLINE];
    char str[INET_ADDRSTRLEN];
    socklen_t cliaddr_len;
    struct sockaddr_in cliaddr, servaddr;

    listenfd = Socket(AF_INET, SOCK_STREAM, 0); /* 将bind的文件描述符变成监听套接字 */

    bzero(&servaddr, sizeof(servaddr)); /* 对servaddr全部清0 */
    servaddr.sin_family = AF_INET; /* 设置地址类型为AF_INE*/
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); /* 网络地址为INADDR_ANY */
    servaddr.sin_port = htons(SERV_PORT); /* IP地址端口号为SERV_PORT */

    Bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)); /* 将本地的端口号同SOCKET返回的文件描述符捆绑在一起*/

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

    maxfd = listenfd; /* initialize *//* 把listenfd赋值给maxfd因为此时只有 listenfd它是最大的*/
    maxi = -1; /* index into client[] array *//* 给maxi赋值为-1 */
    for (i = 0; i < FD_SETSIZE; i++)/* for循环FD_SETSIZE=1024次*/
    client[i] = -1; /* -1 indicates available entry */ /* -1 表示可以利用的*/
    FD_ZERO(&allset); /* 把所有文件描述符集合清零*/
    FD_SET(listenfd, &allset); /* 把listenfd放到文件描述符集合allset里*/

    for ( ; ; ) {/* for 语句的死循环 */
    rset = allset; /* structure assignment *//* 把文件描述符集合allset里的描述符赋值给rset*/
    nready = select(maxfd+1, &rset, NULL, NULL, NULL); /* 调用select并将文件描述符rest赋值给nready*/
    if (nready < 0) /* if条件语句*/
    perr_exit("select error");/*调用 perr_exit输出错误信息并退出*/

    if (FD_ISSET(listenfd, &rset)) { /* new client connection *//* if条件语句 条件调用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) {/* if条件语句 条件client[i] < 0表示client[i]是可以利用的*/
    client[i] = connfd; /* save descriptor *//*把connfd 赋值给client[i]并保存*/
    break; /* 跳出for循环*/
    }
    if (i == FD_SETSIZE) {/* if条件语句 条件i == FD_SETSIZE表示已经出错*/
    fputs("too many clients ", stderr); /* 输出错误信息到 stderr*/
    exit(1); /* 退出*/
    }

    FD_SET(connfd, &allset); /* add new descriptor to set *//* 把connfd存到描述符集合allset里 */
    if (connfd > maxfd) /* if条件语句 条件connfd > maxfd */
    maxfd = connfd; /* for select */ /* 保证maxfd中放到的是最大的*/
    if (i > maxi) /* if条件语句 条件i > maxi */
    maxi = i; /* max index in client[] array *//*maxi 表示已用的 client[i]的最大索引*/

    if (--nready == 0) /* if条件语句 条件nready自减1等于0 */
    continue; /* no more readable descriptors */
    }

    for (i = 0; i <= maxi; i++) { /* check all clients for data *//* for 检查所有的 0到maxi的client[i]里的保存的套接字描述符*/
    if ( (sockfd = client[i]) < 0) /* if条件语句 条件client[i]) < 0表示没保存来自client套接字描述符*/
    continue; /* 继续检测*/
    if (FD_ISSET(sockfd, &rset)) {/* if条件语句 若sockfd在rest中就执行下面语句 */
    if ( (n = Read(sockfd, buf, MAXLINE)) == 0) { /* if条件语句 条件表示客户端关掉了连接 */
    /* connection closed by client */
    Close(sockfd); /* 关掉连接*/
    FD_CLR(sockfd, &allset); /*把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) /* if条件语句 条件nready自减1等于0 */
    break; /* no more readable descriptors */
    }
    }
    }
    }
    执行结果如下:
    [root@localhost ~]# ./service
    Accepting connections ...
    received from 127.0.0.1 at PORT 36967

    [root@localhost ~]# ./client
    aaakhl
    AAAKHL



















    <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>
    阅读(426) | 评论(0) | 转发(1) |
    给主人留下些什么吧!~~
    评论热议
  • 相关阅读:
    ajax请求先发后至问题处理
    Jquery 使用val时触发change事件
    let与var的几个主要区别
    正则表达式s字符匹配
    Ext.DateField设置Format无法提交数据
    swift基本示例
    div 中文会换行 英文不换行
    js 动画提示数据有变化
    为什么要写博客
    突然发现一个开源项目TXQR和我之前申请的一个专利挺像的
  • 原文地址:https://www.cnblogs.com/ztguang/p/12647526.html
Copyright © 2011-2022 走看看