• Linux网络编程之聊天程序(TCP协议之select)


    服务器端:server.c

    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <arpa/inet.h>
    #include <sys/time.h>
    #include <sys/types.h>

    #define MAXBUF 1024

    int main(int argc, char **argv)
    {
            int sockfd, new_fd;
            socklen_t len;
            struct sockaddr_in my_addr, their_addr;
            unsigned int myport, lisnum;
            char buf[MAXBUF + 1];
            fd_set rfds;
            struct timeval tv;
            int retval, maxfd = -1;

            if (argv[2])
                    myport = atoi(argv[2]);       /* 将命令行字符串转换为整数。用于端口 */
            else
                    myport = 8888;                           /* 设置默认端口 */
            if (argv[3])
                    lisnum = atoi(argv[3]);                     /* 监听队列大小 */
            else
                    lisnum = 2;
            if ((sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) {             /* 创建socket对象 */
                    perror("socket");
                    exit(EXIT_FAILURE);
            }

            bzero(&my_addr, sizeof(my_addr));
            my_addr.sin_family = PF_INET;                /* 地址协议 */
            my_addr.sin_port = htons(myport);             /* 地址端口 */
            if (argv[1])
                my_addr.sin_addr.s_addr = inet_addr(argv[1]);
            else
                my_addr.sin_addr.s_addr = INADDR_ANY;                    /* 否则默认本机随意地址 */
            if (bind(sockfd, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1) { /* 绑定地址信息 */
               perror("bind");
               exit(EXIT_FAILURE);
            }
             if (listen(sockfd, lisnum) == -1) {  /* 监听网络 ,最大队列数是lisnum*/
                perror("listen");
                exit(EXIT_FAILURE);
             }

             while (1) 
    {
                printf (" ----wait for new connect ");
                    len = sizeof(struct sockaddr);


                if ((new_fd =accept(sockfd, (struct sockaddr *) &their_addr,&len)) == -1) {

    /* 堵塞等待连接。连接成功返回新的socket描写叙述符,their_addr存储client的sockaddr 地址信息
                perror("accept");
                  exit(errno);
                } else
                printf("server: got connection from %s, port %d, socket %d ", 
    inet_ntoa(their_addr.sin_addr),ntohs(their_addr.sin_port), new_fd);
                while (1) 
    {
                  FD_ZERO(&rfds);     /* 清零rfds集合 */
                    FD_SET(0, &rfds);   /* 把标准输入加入rfds集合 */
                    FD_SET(new_fd, &rfds);                 /* new_fd加入rfds集合 */
                    maxfd = new_fd;
                    tv.tv_sec = 1;
                    tv.tv_usec = 0;
                    retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);    /* maxfd + 1监听的最大值加一 */
                    if (retval == -1) 
    {
    perror("select");
    exit(EXIT_FAILURE);
    } else if (retval == 0) {
                      continue;
                    } 
    else
    {
                        if (FD_ISSET(0, &rfds))                        /* 假设是标准输入可读 */
    {
                              bzero(buf, MAXBUF + 1);
                            fgets(buf, MAXBUF, stdin);
                              if (!strncasecmp(buf, "quit", 4)) {
                                printf("i will quit! ");
                                  break;
                              }
                              len = send(new_fd, buf, strlen(buf) - 1, 0);
                            if (len > 0)
                                    printf ("send successful,%d byte send! ",len);
                              else {
                                  printf("send failure!");
                                break;
                                }
    }
                        if (FD_ISSET(new_fd, &rfds))             /* 假设是new_fd可读 */

                                bzero(buf, MAXBUF + 1);
                              len = recv(new_fd, buf, MAXBUF, 0);
                                if (len > 0)
                                    printf ("recv success :'%s',%dbyte recv ", buf, len);
                                else
    {
                                  if (len < 0)
                                    printf("recv failure ");
                                    else
    {
                                      printf("the ohter one end ,quit ");
                                      break;
    }
                                }
                }
                     }
    }
                close(new_fd);
                printf("need othe connecdt (no->quit)");
                fflush(stdout);
                bzero(buf, MAXBUF + 1);
                fgets(buf, MAXBUF, stdin);
                if (!strncasecmp(buf, "no", 2)) 
    {
                    printf("quit! ");
                    break;
                }
            }
            close(sockfd);
            return 0;
    }

    客户端程序:client.c

    #include <stdio.h>

    #include <string.h>
    #include <errno.h>
    #include <sys/socket.h>
    #include <resolv.h>
    #include <stdlib.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <sys/time.h>
    #include <sys/types.h>

    #define MAXBUF 1024
    int main(int argc, char **argv)
    {
        int sockfd, len;
        struct sockaddr_in dest;
        char buffer[MAXBUF + 1];
        fd_set rfds;
        struct timeval tv;
        int retval, maxfd = -1;

        if (argc != 3) 
        {
            printf("argv format errno,pls: %s IP port ",argv[0], argv[0]);
            exit(EXIT_FAILURE);
        }
        if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
        {
            perror("Socket");
            exit(EXIT_FAILURE);
        }
        bzero(&dest, sizeof(dest));
        dest.sin_family = AF_INET;
        dest.sin_port = htons(atoi(argv[2]));
        if (inet_aton(argv[1], (struct in_addr *) &dest.sin_addr.s_addr) == 0) 
        {
            perror(argv[1]);
            exit(EXIT_FAILURE);
        }

        if (connect(sockfd, (struct sockaddr *) &dest, sizeof(dest)) != 0) 
        {
            perror("Connect ");
            exit(EXIT_FAILURE);
        }

        printf(" get ready pls chat ");
        while (1) 
    {
            FD_ZERO(&rfds);
            FD_SET(0, &rfds);
            FD_SET(sockfd, &rfds);
            maxfd = sockfd;
            tv.tv_sec = 1;
            tv.tv_usec = 0;
            retval = select(maxfd + 1, &rfds, NULL, NULL, &tv);
            if (retval == -1) 
    {
                printf("select %s", strerror(errno));
                break;
            } 
    else if (retval == 0)
                continue;
    else
    {
                if (FD_ISSET(sockfd, &rfds)) 
    {
                    bzero(buffer, MAXBUF + 1);
                    len = recv(sockfd, buffer, MAXBUF, 0);
                    if (len > 0)
                        printf ("recv message:'%s',%d byte recv ",buffer, len);
                    else 
    {
                        if (len < 0)
                            printf ("message recv failure ");
                        else
    {
                            printf("the othe quit ,quit ");
                        break;
    }
                    }
                }
                if (FD_ISSET(0, &rfds)) 
    {
                    bzero(buffer, MAXBUF + 1);
                    fgets(buffer, MAXBUF, stdin);
                    if (!strncasecmp(buffer, "quit", 4)) {
                        printf("i will quit ");
                        break;
                    }
                    len = send(sockfd, buffer, strlen(buffer) - 1, 0);
                    if (len < 0) {
                        printf ("message send failure");
                        break;
                    } else
                        printf
                            ("send success,%d byte send ",len);
                }
            }
        }
        close(sockfd);
        return 0;


    測试方法例如以下:
    gcc server.c -o server
    gcc client.c -o client
    ./server 172.16.148.114  8888       /* 一个终端下。172.16.148.114是我虚拟机的IP地址*/
    ./client 172.16.148.114  8888      /*另外 一个终端下 */

    select函数不会使用的參考这篇文章:http://blog.csdn.net/qq_21792169/article/details/50450360

  • 相关阅读:
    基础语法;
    layabox里面的ui组件之RadioGroup
    github删除带有文件的文件夹
    【转】NHibernate:no persister for 异常
    MVC乱码可能的原因
    【转】局域网内访问VS2012 调试的IIS Express web服务器
    Hightchart y轴不允许显示小数
    WCF 断点不会命中
    Web Form 取消手机端自动转换
    Sharepoint的javascript客户端对象模型获取其他站点的list
  • 原文地址:https://www.cnblogs.com/gccbuaa/p/7306568.html
Copyright © 2020-2023  润新知