• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

               C++ 技術中心

               :: 首頁 :: 聯系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

            鄭重聲明:本BLOG所發表的原創文章,作者保留一切權利。必須經過作者本人同意后方可轉載,并注名作者(天空)和出處(CppBlog.com)。作者Email:coder@luckcoder.com

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評論

            評論排行榜

            #include <sys/epoll.h>
            #include 
            <unistd.h>
            //#include <linux/tcp.h>
            #include <netinet/tcp.h>
            #include 
            <sys/types.h>
            #include 
            <sys/socket.h>
            #include 
            <unistd.h>
            #include 
            <fcntl.h>
            #include 
            <errno.h>
            #include 
            <string.h>
            #include 
            <arpa/inet.h>
            #include 
            <stdio.h>
            #include 
            <vector>
            #include 
            "../../Common/TypeDefine.h"
            #include 
            "../../Common/MemPool.h"


            int32 set_nonblocking(
            int fd)
            {
                int32 oflags;
                
            if ((oflags = fcntl(fd, F_GETFL, 0)) == -1)
                    
            return errno;
                   
                
            if (fcntl(fd, F_SETFL, oflags | O_NONBLOCK) == -1)
                    
            return errno;
                
            return 0;
            }




            int32 epollDel(
            int epfd,struct epoll_event *pEpev)
            {
                 
            return epoll_ctl(epfd, EPOLL_CTL_DEL,pEpev->data.fd, pEpev);
            }


            int32 main(
            int argc,char *argv[])
            {    
                
            //創建套接字
                int32 listenfd = socket(AF_INET,SOCK_STREAM,0);
                
            if(listenfd < 0)
                    
            return -1;
                
                
            //將套接字設為異步
                int32 ret= set_nonblocking(listenfd);
                
            if(ret != 0)
                    
            return -1;
              
                int32 flag 
            = 1;
                setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, 
            &flag, sizeof(flag)); //設置地址端口復用,服務器快速重起
                
                
            // 設置SO_LINGER選項(防范CLOSE_WAIT掛住所有套接字)
                struct linger optval1;
                optval1.l_onoff 
            = 1;
              optval1.l_linger 
            = 60;
              setsockopt(listenfd, SOL_SOCKET, SO_LINGER, 
            &optval1, sizeof(struct linger));
              
                
            //創建epoll
                int32 maxSize = getdtablesize();  //返回某個進程所能打開的最大的文件數
                int32 epfd = epoll_create(maxSize);//創建一個epoll的句柄
                
                
            if(epfd==-1)
                    
            return -1;
                printf(
            "create epoll,maxSize=%d\n",maxSize);
                
                
            //事件注冊
                struct epoll_event epev;
              epev.events 
            = EPOLLIN| EPOLLET;
              epev.data.fd 
            = listenfd;
              
              int32 err 
            = epoll_ctl(epfd, EPOLL_CTL_ADD, listenfd, &epev);
              
              printf(
            "register epoll event finish!\n");
                
                
            //綁定端口
                printf("start bind,port=%d\n",9300);
                
            struct sockaddr_in saddr;
                memset(
            &saddr,0,sizeof(struct sockaddr_in));
                saddr.sin_family 
            = AF_INET;
                saddr.sin_port 
            = htons(9300);
                saddr.sin_addr.s_addr 
            = inet_addr("127.0.0.1");
                
                ret 
            = bind(listenfd,(struct sockaddr *)&saddr,sizeof(struct sockaddr_in));
              
            if(ret < 0)
                
            {
                    
            return -1;
                }


                ret 
            = listen(listenfd,500);

                printf(
            "listen finish!\n");
                

              
              
            //循環
              int32 nev, i, millisecs = 200;
              
            struct epoll_event m_evs[100];
              CHAR buf[
            4096];
              
              
            while(1)
              
            {
                         
            if ((nev = epoll_wait(epfd, m_evs, 100, millisecs)) < 0)
                            
            {
                            
            if (errno == EINTR)
                                
            continue;
                            
            else
                                
            return -1;
                        }

                               
                      
            for (i = 0; i < nev; i++{
                          
                              printf(
            "epoll wait event count=%d\n",nev);
                              
                                       
            if (m_evs[i].data.fd == listenfd)
                                       
            {
                                              
            struct sockaddr_in addr;
                                              socklen_t len 
            = sizeof(addr);
                                              int32 connfd 
            = accept(listenfd,(struct sockaddr *)&addr, &len);
                                              
                                              printf(
            "accept client fd=%d\n",connfd);
                                              
                                              
            if (connfd < 0
                                              
            {
                                                        
            if (errno == EWOULDBLOCK || errno == ECONNABORTED)
                                                        
            {
                                                            printf(
            "Failed to accept new connection (%s).\n", strerror(errno));
                                                        
            continue;
                                                    }

                                                        
            else
                                                                
            {
                                                                    
            //error
                                                                    printf("Failed to accept new connection (%s).\n", strerror(errno));   
                                                                    
            continue;
                                                                }

                                                        }

                                                    
                                                    
            //將套接字設為異步
                                                         if (set_nonblocking(connfd) != 0{
                                                            close(connfd);
                                                        
            return -1;
                                                    }

                                                        
                                                        int32 on
            =1;
                                                    setsockopt(connfd, IPPROTO_TCP, TCP_NODELAY,(
            void *)&on,(socklen_t)sizeof(on));
                                                    
                                        
            struct sockaddr_in clientaddr;
                                        CHAR 
            *str = inet_ntoa(clientaddr.sin_addr);
                                        printf(
            "accapt a connection from %s\n",str);
                                        
                                        
            //設置用于讀操作的文件描述符
                                        struct epoll_event ev;
                                        ev.data.fd
            =connfd;
                                        
            //設置用于注測的讀操作事件
                                        ev.events=EPOLLIN|EPOLLET;
                                        
            //ev.data.ptr = new int8[4097];
                                                        
                                        
            //注冊ev
                                        epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev);
                                        
                                        printf(
            "accept client register epoll event!\n");
                                       }

                                       
            else if(m_evs[i].events&EPOLLIN)//如果是已經連接的用戶,并且收到數據,那么進行讀入
                                       {
                                           printf(
            "EVENT->EPOLLIN\n");
                                           
                                           
            //先屏掉測試
                                           
            //continue;
                                           
                                           
            //如果套接字錯誤
                                           int32 sockfd;
                                           
            if ( (sockfd = m_evs[i].data.fd) < 0)
                                           
            {
                                                 printf(
            "error socket!\n");
                                        
            continue;
                                    }

                                                
                                              int32 rv 
            = 0;
                                              BOOL bClose 
            = FALSE;
                                              int32 totalRv 
            = 0;
                                              
            char buf[4097={0};
                                              
            const int32 maxRead = 10;
                                              
                                              rv 
            = read(m_evs[i].data.fd,buf+totalRv,maxRead-totalRv);
                                                
            while((rv > 0|| (rv < 0 && errno == EINTR))
                                                
            {
                                                      
            if(rv>0)
                                                        
            {
                                                                totalRv 
            += rv;
                                                              printf(
            "read context=[%s]\n",buf);
                                                        }

                                                        printf(
            "read current size = %d,total size=%d\n",rv,totalRv);
                                                        
                                                      
                                                      
            //緩沖區讀滿 
                                                      if(totalRv >= maxRead)
                                                        
            {
                                                                
            break;
                                                        }

                                                        
                                                        rv 
            = read(m_evs[i].data.fd,buf+totalRv,maxRead-totalRv);
                                              }

                                              
                                              
            //對端連接關閉
                                              
            //EAGAIN沒數據,EINTR被中斷
                                              if(rv == 0 ||
                                                  (rv 
            < 0 && errno != EAGAIN && errno!=EINTR) )
                                              
            {
                                                     printf(
            "read fail ,socket will close!\n");
                                                     epollDel(epfd,
            &m_evs[i]);
                                                      close(m_evs[i].data.fd);
                                         m_evs[i].data.fd 
            = -1;
                                         bClose 
            = TRUE;
                                              }

                                              
            else
                                              
            {
                                                   
            //往對端發送寫入數據事件
                                                    struct epoll_event ev;
                                        ev.data.fd
            =m_evs[i].data.fd;
                                        
            //設置用于注測的讀操作事件
                                        
            //ev.events=EPOLLIN|EPOLLOUT|EPOLLET;
                                                        ev.events = m_evs[i].events | EPOLLOUT|EPOLLET;
                                                        
                                        
            //將事件改為寫
                                        int32 ret = epoll_ctl(epfd,EPOLL_CTL_MOD,ev.data.fd,&ev);
                                        printf(
            "end add event ret = %d\n",ret);
                                        
                                        
            if(ret == -1)
                                        
            {
                                              printf(
            "Failed to accept new connection (%s),errno=%d.\n", strerror(errno),errno);
                                        }

                                              }

                                  }

                                  
            else if(m_evs[i].events&EPOLLOUT)
                                  
            {
                                                printf(
            "EVENT->EPOLLOUT\n");
                                                
                                                
            //先不寫數據
                                                
            //continue;
                                                
                                                
                                                int32 sockfd 
            = m_evs[i].data.fd;
                                                
                                                
            char buffer[4096]={0};
                                                
                                                CString str ;
                                                
                                                
            for(int j=0;j<1;j++)
                                                
            {
                                                    str 
            += "0123456789";
                                                }

                                                
                                                strncpy(buffer,str.c_str(),
            4095);
                                                
            char *strPos = buffer;
                                                
            int pos = 0;
                                                
            int len = strlen(buffer);
                                                
                                                
            int rv = write(sockfd,buffer+pos,len-pos);
                                                        
            while((rv >= 0|| (rv < 0 && errno == EINTR))
                                                        
            {
                                                              printf(
            "write current size = %d,total size = %d\n",rv,pos);
                                                                
            if(rv > 0)
                                                                
            {
                                                                     printf(
            "write data size=%d\n",rv);
                                                                }

                                                            
                                                              
            //數據寫完跳出
                                                                if(pos+1==len)
                                                                    
            break;
                                                                
                                                                
                                                                
            if(rv>0)
                                                                  pos 
            += rv;
                                                                
                                                            
            if(len - pos <=0)
                                                            
            {
                                                                printf(
            "send data finish! size = %d\n",len);
                                                                
            break;
                                                            }

                                                                rv 
            = write(sockfd,buffer+pos,len-pos);
                                                        }

                                                        
                                                        
            if(rv < 0 && errno != EAGAIN && errno != EINTR)
                                                        
            {
                                                              printf(
            "write fail ,socket will close!\n");
                                                            epollDel(epfd,
            &m_evs[i]);
                                                               close(m_evs[i].data.fd);
                                                  m_evs[i].data.fd 
            = -1;
                                                        }

                                  }

                                  
            else if (m_evs[i].events&EPOLLERR || m_evs[i].events&EPOLLHUP)
                                  
            {
                                        printf(
            "events error ,socket will close!\n");
                                                    epollDel(epfd,
            &m_evs[i]);
                                                    close(m_evs[i].data.fd);
                                            m_evs[i].data.fd 
            = -1;
                                  }

                              }

               }


            }
            posted on 2013-08-09 10:30 C++技術中心 閱讀(1740) 評論(0)  編輯 收藏 引用 所屬分類: Linux 編程
            996久久国产精品线观看| 欧美日韩精品久久免费| 久久性精品| 热综合一本伊人久久精品| 亚洲欧美伊人久久综合一区二区 | 热99re久久国超精品首页| 久久se精品一区二区影院| 香蕉久久av一区二区三区| 国产精品熟女福利久久AV| 久久青青草原亚洲av无码app| 精品久久久久久无码中文字幕| 亚洲av日韩精品久久久久久a | 无码国内精品久久综合88| 99久久久精品| 午夜人妻久久久久久久久| 久久久久国产精品嫩草影院| 久久99精品久久久久久hb无码| 国产精品久久久久久久久软件| 国内精品久久久久久久coent | 精品久久一区二区三区| 亚洲综合熟女久久久30p| 午夜精品久久久久9999高清| 免费精品99久久国产综合精品| 久久国语露脸国产精品电影| 欧美粉嫩小泬久久久久久久 | 伊人久久大香线蕉综合影院首页| 久久精品国产精品亚洲艾草网美妙 | 色诱久久久久综合网ywww| 国内精品伊人久久久影院| 久久人人爽人爽人人爽av | 久久精品亚洲精品国产欧美| 久久久久久久亚洲Av无码| 亚洲精品午夜国产VA久久成人| 日韩欧美亚洲国产精品字幕久久久 | 久久久久国色AV免费看图片| 久久99精品久久久久久野外| 亚洲国产二区三区久久| 国产精品一区二区久久精品| 久久久久久狠狠丁香| 99久久国产亚洲高清观看2024| 品成人欧美大片久久国产欧美... 品成人欧美大片久久国产欧美 |