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

全部博文(113)

文章存档

2016年(5)

2015年(108)

我的朋友

分类: C/C++

2015-08-18 14:45:34


点击(此处)折叠或打开

  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<errno.h>
  9. #include<netinet/in.h>
  10. #include<arpa/inet.h>
  11. #define MAXLINE 1024
  12. #include<signal.h>
  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. /*避免僵尸进程*/
  109. void handle_sigchld(int sig)
  110. {
  111.     while(waitpid(-1,NULL,WNOHANG)>0)
  112.         ;
  113. }
  114. void echo(int conn)
  115. {
  116.     char recvbuf[1024];
  117.     while(1)
  118.     {    memset(recvbuf,0,sizeof(recvbuf));
  119.         int ret=readline(conn,recvbuf,1024);
  120.         if(ret==-1)
  121.                 die("readline");
  122.         if(ret==0)
  123.         {
  124.             printf("client close\n");
  125.             break;
  126.         }
  127.             fputs(recvbuf,stdout);
  128.             writen(conn,recvbuf,strlen(recvbuf));
  129.     }
  130. }
  131. int main(void)
  132. {/*signal处理僵尸进程*/
  133.     signal(SIGCHLD,handle_sigchld);
  134.     /*socket*/
  135.     int listenfd;
  136.     if((listenfd=socket(AF_INET,SOCK_STREAM,0))<0)
  137.         die("socket");
  138.     /*bind*/
  139.     struct sockaddr_in servaddr;
  140.     memset(&servaddr,0,sizeof(servaddr));
  141.     servaddr.sin_family=AF_INET;
  142.     servaddr.sin_port=htons(5188);
  143.     servaddr.sin_addr.s_addr=htonl(INADDR_ANY);
  144.     /*servaddr.sin_addr.s_addr=inet_addr("127.0.0.1"");*/
  145.     /* if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0) */
  146.     int yes=1;
  147.         if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
  148.             die("reuseaddr");
  149.     if(bind(listenfd,(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
  150.         die("bind");
  151.     /*listen*/
  152.     if(listen(listenfd,SOMAXCONN)<0)
  153.         die("listen");
  154.     /*accept*/
  155.     struct sockaddr_in peeraddr;
  156.     socklen_t peerlen=sizeof(peeraddr);
  157.     int conn;
  158.     /*fork 创建多个进程*/
  159.     pid_t pid;
  160.     while(1){
  161.     if((conn=accept(listenfd,(struct sockaddr*)&peeraddr, &peerlen))<0)
  162.         die("accept");
  163.     printf("ip=%s port=%d\n",inet_ntoa(peeraddr.sin_addr),ntohs(peeraddr.sin_port));
  164.     /*echo function*/
  165.     pid=fork();
  166.     if(pid==-1)
  167.         die("fork");
    if(pid==0)
    {
    close(listenfd);
    echo(conn);
    exit(0);
    }
    else
    close(conn);
    }
    /*close socket*/
    return 0;
    }

点击(此处)折叠或打开

  1. /*5个客户端用signal处理僵尸进程*/
  2. /*echo_client.c*/
  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. #define MAXLINE 1024
  14. void die(char *s)
  15. {perror(s);
  16. exit(0);
  17. }
  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. ssize_t recv_peek(int sockfd,void*buf,size_t len)
  61. {
  62.     while(1)
  63.     {
  64.         int ret=recv(sockfd,buf,len,MSG_PEEK);
  65.         if(ret==-1&errno==EINTR)
  66.             continue;
  67.         return ret;
  68.         
  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. void echo(int sock)
  108. {
  109.     char sendbuf[1024]={0};
  110.     char recvbuf[1024]={0};
  111.     while(fgets(sendbuf,sizeof(sendbuf),stdin)!=NULL)
  112.     {
  113.         writen(sock,sendbuf,strlen(sendbuf));
  114.         int ret=readline(sock,recvbuf,sizeof(recvbuf));
  115.         if(ret==-1)
  116.                 die("read");
  117.         else if(ret==0)
  118.         {
  119.             printf("client close\n");
  120.             break;
  121.         }
  122.         fputs(recvbuf,stdout);
  123.         memset(sendbuf,0,sizeof(sendbuf));
  124.         memset(recvbuf,0,sizeof(recvbuf));
  125.     }
  126.     close(sock);
  127. }
  128. int main(void)
  129. {    
  130.     int sock[5];
  131.     int i;
  132.     for(i=0;i<5;i++){
  133.     /*socket*/
  134.     if((sock[i]=socket(AF_INET,SOCK_STREAM,0))<0)
  135.         die("socket");
  136.     struct sockaddr_in servaddr;
  137.     memset(&servaddr,0,sizeof(servaddr));
  138.     servaddr.sin_family=AF_INET;
  139.     servaddr.sin_port=htons(5188);
  140.     /* servaddr.sin_addr.s_addr=htonl(INADDR_ANY); */
  141.     servaddr.sin_addr.s_addr=inet_addr("127.0.0.1");
  142.     /*connect*/
  143.     if(connect(sock[i],(struct sockaddr*)&servaddr,sizeof(servaddr))<0)
  144.         die("connect");
  145.     /*getsockname function*/
  146.     /*return local addr port*/
  147.     struct sockaddr_in localaddr;
  148.     socklen_t addrlen=sizeof(localaddr);
  149.     if(getsockname(sock[i],(struct sockaddr*)&localaddr,&addrlen)<0)
  150.         die("getsockname");
  151.     printf("ip=%s port=%d\n",inet_ntoa(localaddr.sin_addr),ntohs(localaddr.sin_port));

  152.     
  153. }
  154.     echo(sock[0]);
  155.     return 0;
  156. }


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