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

全部博文(113)

文章存档

2016年(5)

2015年(108)

我的朋友

分类: C/C++

2015-08-17 22:45:54

解决粘包问题的readline function的回射客户端,服务器

点击(此处)折叠或打开

  1. /*解决粘包问题*/
  2. #include<stdio.h>
  3. #include<sys/types.h>
  4. #include<string.h>
  5. #include<sys/socket.h>
  6. #include<unistd.h>
  7. #include<stdlib.h>
  8. #include<signal.h>
  9. #include<errno.h>
  10. #include<netinet/in.h>
  11. #include<arpa/inet.h>
  12. #define MAXLINE 1024
  13. void die(char *s)
  14. {perror(s);
  15. exit(0);
  16. }
  17. /*readn*/
  18. ssize_t readn(int fd, void *buf,size_t count)
  19. {
  20.     size_t nleft=count;
  21.     ssize_t nread;
  22.     char *bufp=(char*)buf;
  23.     while(nleft>0)
  24.     {
  25.         if((nread=read(fd,bufp,nleft))<0)
  26.         {
  27.             if(errno==EINTR)
  28.                 continue;
  29.             return -1;
  30.         }
  31.         else if(nread==0)
  32.             return count-nleft;
  33.         bufp+=nread;
  34.         nleft-=nread;
  35.     }
  36.     return count;
  37.     
  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. }
  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 do_service(int conn)
  109. {
  110.     char recvbuf[1024];
  111.     while(1)
  112.     {    memset(recvbuf,0,sizeof(recvbuf));
  113.         int ret=readline(conn,recvbuf,1024);
  114.         if(ret==-1)
  115.                 die("readline");
  116.         if(ret==0)
  117.         {
  118.             printf("client close\n");
  119.             break;
  120.         }
  121.             fputs(recvbuf,stdout);
  122.             writen(conn,recvbuf,strlen(recvbuf));
  123.     }
  124. }
  125. int main(void)
  126. {  /*signal处理僵尸进程*/
    signal(SIGCHLD,SIG_IGN);

  127.     /*socket*/
  128.     int listenfd;
  129.     if((listenfd=socket(AF_INET,SOCK_STREAM,0))<0)
  130.         die("socket");
  131.     /*bind*/
  132.     struct sockaddr_in servaddr;
  133.     memset(&servaddr,0,sizeof(servaddr));
  134.     servaddr.sin_family=AF_INET;
  135.     servaddr.sin_port=htons(5188);
  136.     servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
  137.     /*servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"");*/
  138.     /* if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) */
  139.     int yes=1;
  140.         if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
  141.             die("reuseaddr");
  142.     if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
  143.         die("bind");
  144.     /*listen*/
  145.     if(listen(listenfd,SOMAXCONN)<0)
  146.         die("listen");
  147.     /*accept*/
  148.     struct sockaddr_in peeraddr;
  149.     socklen_t peerlen=sizeof(peeraddr);
  150.     int conn;
  151.     /*fork 创建多个进程*/
  152.     pid_t pid;
  153.     while(1){
  154.     if((conn=accept(listenfd,(struct sockaddr*)&peeraddr, &peerlen))<0)
  155.         die("accept");
  156.     printf("ip=%s port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
  157.     /*echo function*/
  158.     pid=fork();
  159.     if(pid==-1)
  160.         die("fork");
    if(pid==0)
    {
    close(listenfd);
    do_service(conn);
    exit(0);
    }
    else
    close(conn);
    }
    /*close socket*/
    return 0;
    }

点击(此处)折叠或打开

  1. /*echo_client.c*/
  2. #include<stdio.h>
  3. #include<sys/types.h>
  4. #include<string.h>
  5. #include<sys/socket.h>
  6. #include<unistd.h>
  7. #include<stdlib.h>
  8. #include<errno.h>
  9. #include<netinet/in.h>
  10. #include<arpa/inet.h>
  11. #define MAXLINE 1024
  12. void die(char *s)
  13. {perror(s);
  14. exit(0);
  15. }
  16. ssize_t readn(int fd, void *buf,size_t count)
  17. {
  18.     size_t nleft=count;
  19.     ssize_t nread;
  20.     char *bufp=(char*)buf;
  21.     while(nleft>0)
  22.     {
  23.         if((nread=read(fd,bufp,nleft))<0)
  24.         {
  25.             if(errno==EINTR)
  26.                 continue;
  27.             return -1;
  28.         }
  29.         else if(nread==0)
  30.             return count-nleft;
  31.         bufp+=nread;
  32.         nleft-=nread;
  33.     }
  34.     return count;
  35.     
  36. }
  37. /*writen*/
  38. ssize_t writen(int fd,void* buf,size_t count)
  39. {
  40.     size_t nleft=count;
  41.     ssize_t nwrite;
  42.     char *bufp=(char*)buf;
  43.     while(nleft>0)
  44.     {
  45.         if((nwrite=write(fd,bufp,nleft))<0)
  46.         {
  47.             if(errno==EINTR)
  48.                 continue;
  49.             return -1;
  50.         }
  51.         else if(nwrite==0)
  52.             continue;
  53.         bufp+=nwrite;
  54.         nleft-=nwrite;
  55.     }
  56.     return count;
  57. }
  58. ssize_t recv_peek(int sockfd,void*buf,size_t len)
  59. {
  60.     while(1)
  61.     {
  62.         int ret=recv(sockfd,buf,len,MSG_PEEK);
  63.         if(ret==-1&errno==EINTR)
  64.             continue;
  65.         return ret;
  66.         
  67.     }
  68. }
  69. /*readline function*/
  70. ssize_t readline(int sockfd,void *buf,size_t len)
  71. {
  72.     int ret;
  73.     int nread;
  74.     char *bufp=buf;
  75.     int nleft=MAXLINE;
  76.     while(1)
  77.     {
  78.         ret=recv_peek(sockfd,bufp,nleft);
  79.         if(ret<0)
  80.             return ret;
  81.         else if(ret==0)
  82.             return ret;
  83.         nread=ret;
  84.         int i;
  85.         for(i=0;i<nread;i++)
  86.         {
  87.             if(bufp[i]=='\n')
  88.             {
  89.                 ret=readn(sockfd,bufp,i+1);
  90.                 if(ret!=i+1)
  91.                     exit(1);
  92.                 return ret;
  93.             }
  94.         }
  95.         if(nread>nleft)
  96.             exit(1);
  97.         nleft-=nread;
  98.         ret=readn(sockfd,bufp,nread);
  99.         if(ret!=nread)
  100.             exit(1);
  101.         bufp+=nread;
  102.     }
  103.     return -1;
  104. }
  105. int main(void)
  106. {
  107.     /*socket*/
  108.     int sock;
  109.     if((sock=socket(AF_INET,SOCK_STREAM,0))<0)
  110.         die("socket");
  111.     struct sockaddr_in servaddr;
  112.     memset(&servaddr,0,sizeof(servaddr));
  113.     servaddr.sin_family=AF_INET;
  114.     servaddr.sin_port=htons(5188);
  115.     /* servaddr.sin_addr.s_addr=htonl(INADDR_ANY); */
  116.     servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
  117.     /*connect*/
  118.     if(connect(sock,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
  119.         die("connect");
  120.     char sendbuf[1024]={0};
  121.     char recvbuf[1024]={0};
  122.     while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
  123.     {
  124.         writen(sock,sendbuf,strlen(sendbuf));
  125.         int ret=readline(sock,recvbuf,sizeof(recvbuf));
  126.         if(ret==-1)
  127.                 die("read");
  128.         else if(ret==0)
  129.         {
  130.             printf("client close\n");
  131.             break;
  132.         }
  133.         fputs(recvbuf,stdout);
  134.         memset(sendbuf,0,sizeof(sendbuf));
  135.         memset(recvbuf,0,sizeof(recvbuf));
  136.     }
  137.     close(sock);
  138.     return 0;
  139. }


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