Chinaunix首页 | 论坛 | 博客
  • 博客访问: 237058
  • 博文数量: 113
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1044
  • 用 户 组: 普通用户
  • 注册时间: 2015-02-15 16:09
文章分类

全部博文(113)

文章存档

2016年(5)

2015年(108)

我的朋友

分类: C/C++

2015-08-22 00:07:58


点击(此处)折叠或打开

  1. /*select server*/
  2. #include<stdio.h>
  3. #include<sys/types.h>
  4. #include<sys/select.h>
  5. #include<string.h>
  6. #include<sys/socket.h>
  7. #include<unistd.h>
  8. #include<stdlib.h>
  9. #include<errno.h>
  10. #include<netinet/in.h>
  11. #include<arpa/inet.h>
  12. #define MAXLINE 1024
  13. #include<signal.h>
  14. void die(char *s)
  15. {perror(s);
  16. exit(0);
  17. }
  18. /*readn*/
  19. ssize_t readn(int fd, void *buf,size_t count)
  20. {
  21.     size_t nleft=count;
  22.     ssize_t nread;
  23.     char *bufp=(char*)buf;
  24.     while(nleft>0)
  25.     {
  26.         if((nread=read(fd,bufp,nleft))<0)
  27.         {
  28.             if(errno==EINTR)
  29.                 continue;
  30.             return -1;
  31.             }
  32.         else if(nread==0)
  33.         return count-nleft;
  34.         bufp+=nread;
  35.         nleft-=nread;
  36.         }
  37.     return count;
  38. }
  39. /*writen*/
  40. ssize_t writen(int fd,void* buf,size_t count)
  41. {
  42.     size_t nleft=count;
  43.     ssize_t nwrite;
  44.     char *bufp=(char*)buf;
  45.     while(nleft>0)
  46.     {
  47.         if((nwrite=write(fd,bufp,nleft))<0)
  48.         {
  49.             if(errno==EINTR)
  50.                 continue;
  51.             return -1;
  52.         }
  53.         else if(nwrite==0)
  54.             continue;
  55.         bufp+=nwrite;
  56.         nleft-=nwrite;
  57.     }
  58.     return count;
  59. }
  60. /*recv_peek function*/
  61. ssize_t recv_peek(int sockfd,void*buf,size_t len)
  62. {
  63.     while(1)
  64.     {
  65.         int ret=recv(sockfd,buf,len,MSG_PEEK);
  66.         if(ret==-1&errno==EINTR)
  67.             continue;
  68.         return ret;
  69.     }
  70. }
  71.     /*readline function*/
  72. ssize_t readline(int sockfd,void *buf,size_t len)
  73. {
  74.     int ret;
  75.     int nread;
  76.     char *bufp=buf;
  77.     int nleft=MAXLINE;
  78.     while(1)
  79.     {
  80.         ret=recv_peek(sockfd,bufp,nleft);
  81.         if(ret<0)
  82.             return ret;
  83.         else if(ret==0)
  84.             return ret;
  85.         nread=ret;
  86.         int i;
  87.         for(i=0;i<nread;i++)
  88.         {
  89.         if(bufp[i]=='\n')
  90.             {
  91.                 ret=readn(sockfd,bufp,i+1);
  92.                 if(ret!=i+1)
  93.                     exit(1);
  94.                 return ret;
  95.             }
  96.         }
  97.         if(nread>nleft)
  98.             exit(1);
  99.         nleft-=nread;
  100.         ret=readn(sockfd,bufp,nread);
  101.         if(ret!=nread)
  102.             exit(1);
  103.         bufp+=nread;
  104.     }
  105.     return -1;
  106. }
  107. /*避免僵尸进程*/
  108. void handle_sigchld(int sig)
  109. {
  110.     while(waitpid(-1,NULL,WNOHANG)>0)
  111.         ;
  112. }
  113. /* void echo(int conn)
  114. {
  115.     char recvbuf[1024];
  116.     while(1)
  117.     {    memset(recvbuf,0,sizeof(recvbuf));
  118.         int ret=readline(conn,recvbuf,1024);
  119.         if(ret==-1)
  120.             die("readline");
  121.         if(ret==0)
  122.         {
  123.             printf("client close\n");
  124.             break;
  125.         }
  126.             fputs(recvbuf,stdout);
  127.             writen(conn,recvbuf,strlen(recvbuf));
  128.     }
  129. } */
  130. int main(void)
  131. {    /*signal处理僵尸进程*/
  132.     signal(SIGCHLD,handle_sigchld);
  133.     /*socket*/
  134.     int listenfd;
  135.     if((listenfd=socket(AF_INET,SOCK_STREAM,0))<0)
  136.         die("socket");
  137.     /*bind*/
  138.     struct sockaddr_in servaddr;
  139.     memset(&servaddr,0,sizeof(servaddr));
  140.     servaddr.sin_family=AF_INET;
  141.     servaddr.sin_port=htons(5188);
  142.     servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
  143.     /*servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"");*/
  144.     /* if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) */
  145.         int yes=1;
  146.         if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
  147.             die("reuseaddr");
  148.     if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
  149.             die("bind");
  150.         /*listen*/
  151.     if(listen(listenfd,SOMAXCONN)<0)
  152.         die("listen");
  153.     /*accept*/
  154.     struct sockaddr_in peeraddr;
  155.     socklen_t peerlen;
  156.     int conn;
  157.     /*fork 创建多个进程*/
  158. /*     pid_t pid;
  159.     while(1){
  160.     if((conn=accept(listenfd,(struct sockaddr*)&peeraddr, &peerlen))<0)
  161.         die("accept");
  162.     printf("ip=%s port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
  163.     /*echo function*/
  164. /*     pid=fork();
  165.     if(pid==-1)
  166.         die("fork");
  167. if(pid==0)
  168. {
  169. close(listenfd);
  170. echo(conn);
  171. exit(0);
  172. }
  173. else
  174. close(conn);
  175. } */
  176. int client[FD_SETSIZE];
  177. int i;
  178. for(i=0;i<FD_SETSIZE;i++)
  179.     client[i]=-1;
  180. /*select*/
  181. int nready;//检测到的描述符
  182. int maxfd=listenfd;
  183. fd_set rset;
  184. fd_set allset;
  185. FD_ZERO(&rset);
  186. FD_ZERO(&allset);
  187. FD_SET(listenfd,&allset);
  188. while(1){
  189.     rset=allset;
  190.     nready=select(maxfd+1,&rset,NULL,NULL,NULL);
  191.     if(nready==-1)
  192.     {
  193.         if(errno==EINTR)
  194.             continue;
  195.         else die("select");
  196.     }
  197.     if(nready==0)
  198.         continue;
  199.     /*z自己写入数据*/
  200.     if(FD_ISSET(listenfd,&rset))
  201.     {    peerlen=sizeof(peeraddr);
  202.         conn=accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen);
  203.         if(conn==-1)
  204.             die("accept");
  205.         for(i=0;i<FD_SETSIZE;i++)
  206.         {
  207.             if(client[i]<0)
  208.             {client[i]=conn;
  209.                 break;
  210.             }
  211.         }
  212.         if(i==FD_SETSIZE)
  213.         {
  214.             fprintf(stdout,"too many client");
  215.             exit(1);
  216.         }
  217.         printf("ip=%s port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
  218.         FD_SET(conn,&allset);
  219.         if(conn>maxfd)
  220.             maxfd=conn;
  221.         if(--nready<=0)
  222.             continue;
  223.     }
  224.     /*数据来自对方的发送*/
  225.     for(i=0;i<FD_SETSIZE;i++)
  226.     {
  227.         conn=client[i];
  228.         if(conn==-1)
  229.             continue;
  230.         if(FD_ISSET(conn,&rset))
  231.         {
  232.             /*读的集合来自客户端,进行回射服务*/
  233.             char recvbuf[1024]={0};
  234.         int ret=readline(conn,recvbuf,1024);
  235.         if(ret==-1)
  236.             die("readline");
  237.         if(ret==0)
  238.         {
  239.             printf("client close\n");
    /*如果错误,从集合当中清除*/
    FD_CLR(conn,&allset);
    }
    fputs(recvbuf,stdout);
    writen(conn,recvbuf,strlen(recvbuf));
    if(--nready<=0)
    break;
    }
    }




    }
    /*close socket*/ 
    return 0;
    }

点击(此处)折叠或打开

  1. /*echo_client.c*/
  2. /*select改进的client*/
  3. #include<stdio.h>
  4. #include<sys/types.h>
  5. #include<string.h>
  6. #include<sys/socket.h>
  7. #include<unistd.h>
  8. #include<stdlib.h>
  9. #include<errno.h>
  10. #include<netinet/in.h>
  11. #include<arpa/inet.h>
  12. #include <netdb.h>
  13. #include<signal.h>
  14. #define MAXLINE 1024
  15. void die(char *s)
  16. {perror(s);
  17. exit(0);
  18. }
  19. ssize_t readn(int fd, void *buf,size_t count)
  20. {
  21.     size_t nleft=count;
  22.     ssize_t nread;
  23.     char *bufp=(char*)buf;
  24.     while(nleft>0)
  25.     {
  26.         if((nread=read(fd,bufp,nleft))<0)
  27.         {
  28.             if(errno==EINTR)
  29.                 continue;
  30.             return -1;
  31.         }
  32.         else if(nread==0)
  33.             return count-nleft;
  34.         bufp+=nread;
  35.         nleft-=nread;
  36.     }
  37.     return count;
  38.     
  39. }
  40. /*writen*/
  41. ssize_t writen(int fd,void* buf,size_t count)
  42. {
  43.     size_t nleft=count;
  44.     ssize_t nwrite;
  45.     char *bufp=(char*)buf;
  46.     while(nleft>0)
  47.     {
  48.         if((nwrite=write(fd,bufp,nleft))<0)
  49.         {
  50.             if(errno==EINTR)
  51.                 continue;
  52.             return -1;
  53.         }
  54.         else if(nwrite==0)
  55.             continue;
  56.         bufp+=nwrite;
  57.         nleft-=nwrite;
  58.     }
  59.     return count;
  60. }
  61. ssize_t recv_peek(int sockfd,void*buf,size_t len)
  62. {
  63.     while(1)
  64.     {
  65.         int ret=recv(sockfd,buf,len,MSG_PEEK);
  66.         if(ret==-1&errno==EINTR)
  67.             continue;
  68.         return ret;
  69.         
  70.     }
  71. }
  72. /*readline function*/
  73. ssize_t readline(int sockfd,void *buf,size_t len)
  74. {
  75.     int ret;
  76.     int nread;
  77.     char *bufp=buf;
  78.     int nleft=MAXLINE;
  79.     while(1)
  80.     {
  81.         ret=recv_peek(sockfd,bufp,nleft);
  82.         if(ret<0)
  83.             return ret;
  84.         else if(ret==0)
  85.             return ret;
  86.         nread=ret;
  87.         int i;
  88.         for(i=0;i<nread;i++)
  89.         {
  90.             if(bufp[i]=='\n')
  91.             {
  92.                 ret=readn(sockfd,bufp,i+1);
  93.                 if(ret!=i+1)
  94.                     exit(1);
  95.                 return ret;
  96.             }
  97.         }
  98.         if(nread>nleft)
  99.             exit(1);
  100.         nleft-=nread;
  101.         ret=readn(sockfd,bufp,nread);
  102.         if(ret!=nread)
  103.             exit(1);
  104.         bufp+=nread;
  105.     }
  106.     return -1;
  107. }
  108. void handle_sigchld(int sig)
  109. {
  110.     printf("recv a sig=%d\n",sig);
  111. }
  112. void echo(int sock)
  113. {
  114.     /* char sendbuf[1024]={0};
  115.     char recvbuf[1024]={0};
  116.     while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
  117.     {
  118.         writen(sock,sendbuf,strlen(sendbuf));
  119.         int ret=readline(sock,recvbuf,sizeof(recvbuf));
  120.         if(ret==-1)
  121.                 die("read");
  122.         else if(ret==0)
  123.         {
  124.             printf("client close\n");
  125.             break;
  126.         }
  127.         fputs(recvbuf,stdout);
  128.         memset(sendbuf,0,sizeof(sendbuf));
  129.         memset(recvbuf,0,sizeof(recvbuf));
  130.     }
  131.     close(sock); */
  132.     /*select*/
  133.     char recvbuf[1024]={0};
  134.     char sendbuf[1024]={0};
  135.     fd_set rset;
  136.     FD_ZERO(&rset);
  137.     int nready;
  138.     int maxfd;
  139.     int fd_stdin=fileno(stdin);
  140.     if(fd_stdin>sock)
  141.             maxfd=fd_stdin;
  142.         else
  143.             maxfd=sock;
  144.     while(1)
  145.     {    FD_SET(fd_stdin,&rset);
  146.         FD_SET(sock,&rset);
  147.         nready=select(maxfd+1,&rset,NULL,NULL,NULL);
  148.         if(nready==-1)
  149.             die("select");
  150.         if(nready==0)
  151.             continue;
  152.         /*sock产生可读事件*/
  153.         if(FD_ISSET(sock,&rset))
  154.         {
  155.             int ret=readline(sock,recvbuf,1024);
  156.         if(ret==-1)
  157.                 die("readline");
  158.         if(ret==0)
  159.         {
  160.             printf("server close\n");
  161.             break;
  162.         }
  163.             fputs(recvbuf,stdout);
  164.             memset(recvbuf,0,sizeof(recvbuf));
  165.         }
  166.         /*stdin*/
  167.         if(FD_ISSET(fd_stdin,&rset))
  168.         {
  169.             if(fgets(sendbuf,sizeof(sendbuf),stdin)==NULL)
  170.             break;
  171.             writen(sock,sendbuf,strlen(sendbuf));
  172.             memset(sendbuf,0,sizeof(sendbuf));
  173.         }

  174.     }
  175.     close(sock);
  176. }
  177. int main(void)
  178. {    signal(SIGPIPE,SIG_IGN);
  179.     int sock;
  180.     int i;
  181.     
  182.     /*socket*/
  183.     if((sock=socket(AF_INET,SOCK_STREAM,0))<0)
  184.         die("socket");
  185.     struct sockaddr_in servaddr;
  186.     memset(&servaddr,0,sizeof(servaddr));
  187.     servaddr.sin_family=AF_INET;
  188.     servaddr.sin_port=htons(5188);
  189.     /* servaddr.sin_addr.s_addr=htonl(INADDR_ANY); */
  190.     servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
  191.     /*sockect*/
  192.     if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
  193.         die("connect");
  194.     /*getsockname function*/
  195.     /*return local addr port*/
  196.     struct sockaddr_in localaddr;
  197.     socklen_t addrlen=sizeof(localaddr);
  198.     if(getsockname(sock,(struct sockaddr*)&localaddr,&addrlen)<0)
  199.         die("getsockname");
  200.     printf("ip=%s port=%d\n",inet_ntoa(localaddr.sin_addr),ntohs(localaddr.sin_port));

  201.     

  202.     echo(sock);
  203.     return 0;
  204. }
改进的select服务器:

点击(此处)折叠或打开

  1. /*select server*/
  2. #include<stdio.h>
  3. #include<sys/types.h>
  4. #include<sys/select.h>
  5. #include<string.h>
  6. #include<sys/socket.h>
  7. #include<unistd.h>
  8. #include<stdlib.h>
  9. #include<errno.h>
  10. #include<netinet/in.h>
  11. #include<arpa/inet.h>
  12. #define MAXLINE 1024
  13. #include<signal.h>
  14. void die(char *s)
  15. {perror(s);
  16. exit(0);
  17. }
  18. /*readn*/
  19. ssize_t readn(int fd, void *buf,size_t count)
  20. {
  21.     size_t nleft=count;
  22.     ssize_t nread;
  23.     char *bufp=(char*)buf;
  24.     while(nleft>0)
  25.     {
  26.         if((nread=read(fd,bufp,nleft))<0)
  27.         {
  28.             if(errno==EINTR)
  29.                 continue;
  30.             return -1;
  31.             }
  32.         else if(nread==0)
  33.         return count-nleft;
  34.         bufp+=nread;
  35.         nleft-=nread;
  36.         }
  37.     return count;
  38. }
  39. /*writen*/
  40. ssize_t writen(int fd,void* buf,size_t count)
  41. {
  42.     size_t nleft=count;
  43.     ssize_t nwrite;
  44.     char *bufp=(char*)buf;
  45.     while(nleft>0)
  46.     {
  47.         if((nwrite=write(fd,bufp,nleft))<0)
  48.         {
  49.             if(errno==EINTR)
  50.                 continue;
  51.             return -1;
  52.         }
  53.         else if(nwrite==0)
  54.             continue;
  55.         bufp+=nwrite;
  56.         nleft-=nwrite;
  57.     }
  58.     return count;
  59. }
  60. /*recv_peek function*/
  61. ssize_t recv_peek(int sockfd,void*buf,size_t len)
  62. {
  63.     while(1)
  64.     {
  65.         int ret=recv(sockfd,buf,len,MSG_PEEK);
  66.         if(ret==-1&errno==EINTR)
  67.             continue;
  68.         return ret;
  69.     }
  70. }
  71.     /*readline function*/
  72. ssize_t readline(int sockfd,void *buf,size_t len)
  73. {
  74.     int ret;
  75.     int nread;
  76.     char *bufp=buf;
  77.     int nleft=MAXLINE;
  78.     while(1)
  79.     {
  80.         ret=recv_peek(sockfd,bufp,nleft);
  81.         if(ret<0)
  82.             return ret;
  83.         else if(ret==0)
  84.             return ret;
  85.         nread=ret;
  86.         int i;
  87.         for(i=0;i<nread;i++)
  88.         {
  89.         if(bufp[i]=='\n')
  90.             {
  91.                 ret=readn(sockfd,bufp,i+1);
  92.                 if(ret!=i+1)
  93.                     exit(1);
  94.                 return ret;
  95.             }
  96.         }
  97.         if(nread>nleft)
  98.             exit(1);
  99.         nleft-=nread;
  100.         ret=readn(sockfd,bufp,nread);
  101.         if(ret!=nread)
  102.             exit(1);
  103.         bufp+=nread;
  104.     }
  105.     return -1;
  106. }
  107. /*避免僵尸进程*/
  108. void handle_sigchld(int sig)
  109. {
  110.     while(waitpid(-1,NULL,WNOHANG)>0)
  111.         ;
  112. }
  113. /* void echo(int conn)
  114. {
  115.     char recvbuf[1024];
  116.     while(1)
  117.     {    memset(recvbuf,0,sizeof(recvbuf));
  118.         int ret=readline(conn,recvbuf,1024);
  119.         if(ret==-1)
  120.             die("readline");
  121.         if(ret==0)
  122.         {
  123.             printf("client close\n");
  124.             break;
  125.         }
  126.             fputs(recvbuf,stdout);
  127.             writen(conn,recvbuf,strlen(recvbuf));
  128.     }
  129. } */
  130. int main(void)
  131. {    /*signal处理僵尸进程*/
  132.     signal(SIGCHLD,handle_sigchld);
  133.     /*socket*/
  134.     int listenfd;
  135.     if((listenfd=socket(AF_INET,SOCK_STREAM,0))<0)
  136.         die("socket");
  137.     /*bind*/
  138.     struct sockaddr_in servaddr;
  139.     memset(&servaddr,0,sizeof(servaddr));
  140.     servaddr.sin_family=AF_INET;
  141.     servaddr.sin_port=htons(5188);
  142.     servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
  143.     /*servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"");*/
  144.     /* if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) */
  145.         int yes=1;
  146.         if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
  147.             die("reuseaddr");
  148.     if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
  149.             die("bind");
  150.         /*listen*/
  151.     if(listen(listenfd,SOMAXCONN)<0)
  152.         die("listen");
  153.     /*accept*/
  154.     struct sockaddr_in peeraddr;
  155.     socklen_t peerlen;
  156.     int conn;
  157.     /*fork 创建多个进程*/
  158. /*     pid_t pid;
  159.     while(1){
  160.     if((conn=accept(listenfd,(struct sockaddr*)&peeraddr, &peerlen))<0)
  161.         die("accept");
  162.     printf("ip=%s port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
  163.     /*echo function*/
  164. /*     pid=fork();
  165.     if(pid==-1)
  166.         die("fork");
  167. if(pid==0)
  168. {
  169. close(listenfd);
  170. echo(conn);
  171. exit(0);
  172. }
  173. else
  174. close(conn);
  175. } */
  176. int client[FD_SETSIZE];
  177. int i;
  178. for(i=0;i<FD_SETSIZE;i++)
  179.     client[i]=-1;
  180. /*select*/
  181. int maxi=0;
  182. int nready;//检测到的描述符
  183. int maxfd=listenfd;
  184. fd_set rset;
  185. fd_set allset;
  186. FD_ZERO(&rset);
  187. FD_ZERO(&allset);
  188. FD_SET(listenfd,&allset);
  189. while(1){
  190.     rset=allset;
  191.     nready=select(maxfd+1,&rset,NULL,NULL,NULL);
  192.     if(nready==-1)
  193.     {
  194.         if(errno==EINTR)
  195.             continue;
  196.         else die("select");
  197.     }
  198.     if(nready==0)
  199.         continue;
  200.     /*z自己写入数据*/
  201.     if(FD_ISSET(listenfd,&rset))
  202.     {    peerlen=sizeof(peeraddr);
  203.         conn=accept(listenfd,(struct sockaddr*)&peeraddr,&peerlen);
  204.         if(conn==-1)
  205.             die("accept");
  206.         for(i=0;i<FD_SETSIZE;i++)
  207.         {
  208.             if(client[i]<0)
  209.             {client[i]=conn;
  210.                 if(i>maxi)
  211.                 maxi=i;
  212.                 break;
  213.             }
  214.         }
  215.         if(i==FD_SETSIZE)
  216.         {
  217.             fprintf(stdout,"too many client");
  218.             exit(1);
  219.         }
  220.         printf("ip=%s port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
  221.         FD_SET(conn,&allset);
  222.         if(conn>maxfd)
  223.             maxfd=conn;
  224.         if(--nready<=0)
  225.             continue;
  226.     }
  227.     /*数据来自对方的发送*/
  228.     for(i=0;i<=maxi;i++)
  229.     {
  230.         conn=client[i];
  231.         if(conn==-1)
  232.             continue;
  233.         if(FD_ISSET(conn,&rset))
  234.         {
  235.             /*读的集合来自客户端,进行回射服务*/
  236.             char recvbuf[1024]={0};
  237.         int ret=readline(conn,recvbuf,1024);
  238.         if(ret==-1)
  239.             die("readline");
  240.         if(ret==0)
  241.         {
  242.             printf("client close\n");
    /*如果错误,从集合当中清除*/
    FD_CLR(conn,&allset);
    client[i]=-1;
    }
    fputs(recvbuf,stdout);
    writen(conn,recvbuf,strlen(recvbuf));
    if(--nready<=0)
    break;
    }
    }




    }
    /*close socket*/ 
    return 0;
    }



阅读(1064) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~