码迷,mamicode.com
首页 > 其他好文 > 详细

LT和ET模式

时间:2015-04-24 18:50:00      阅读:160      评论:0      收藏:0      [点我收藏+]

标签:

  1 #include <sys/types.h>
  2 #include <sys/socket.h>
  3 #include <netinet/in.h>
  4 #include <arpa/inet.h>
  5 #include <assert.h>
  6 #include <stdio.h>
  7 #include <unistd.h>
  8 #include <errno.h>
  9 #include <string.h>
 10 #include <fcntl.h>
 11 #include <stdlib.h>
 12 #include <sys/epoll.h>
 13 #include <pthread.h>
 14 #include <libgen.h> 
 15 #include <strings.h> 
 16 #define MAX_EVENT_NUMBER 1024
 17 #define BUFFER_SIZE 10
 18 
 19 int setnonblocking( int fd )
 20 {
 21     int old_option = fcntl( fd, F_GETFL );
 22     int new_option = old_option | O_NONBLOCK;
 23     fcntl( fd, F_SETFL, new_option );
 24     return old_option;
 25 }
 26 void addfd( int epollfd, int fd, int enable_et )
 27 {
 28     struct epoll_event event;
 29     event.data.fd = fd;
 30     event.events = EPOLLIN;
 31     if( enable_et )
 32     {
 33         event.events |= EPOLLET;
 34     }
 35     epoll_ctl( epollfd, EPOLL_CTL_ADD, fd, &event );
 36     setnonblocking( fd );
 37 }
 38 
 39 void lt( struct epoll_event * events, int number, int epollfd, int listenfd )
 40 {
 41     char buf[ BUFFER_SIZE ];
 42     for ( int i = 0; i < number; i++ )
 43     {
 44         int sockfd = events[i].data.fd;
 45         if ( sockfd == listenfd )
 46         {
 47             struct sockaddr_in client_address;
 48             socklen_t client_addrlength = sizeof( client_address );
 49             int connfd = accept( listenfd, ( struct sockaddr* )&client_address, &client_addrlength );
 50             addfd( epollfd, connfd, 0 );
 51         }
 52         else if ( events[i].events & EPOLLIN )
 53         {
 54             printf( "event trigger once\n" );
 55             memset( buf, \0, BUFFER_SIZE );
 56             int ret = recv( sockfd, buf, BUFFER_SIZE-1, 0 );
 57             if( ret <= 0 )
 58             {
 59                 close( sockfd );
 60                 continue;
 61             }
 62             printf( "get %d bytes of content: %s\n", ret, buf );
 63         }
 64         else
 65         {
 66             printf( "something else happened \n" );
 67         }
 68     }
 69 }
 70 
 71 void et( struct epoll_event *events, int number, int epollfd, int listenfd )
 72 {
 73     char buf[ BUFFER_SIZE ];
 74     for ( int i = 0; i < number; i++ )
 75     {
 76         int sockfd = events[i].data.fd;
 77         if ( sockfd == listenfd )
 78         {
 79             struct sockaddr_in client_address;
 80             socklen_t client_addrlength = sizeof( client_address );
 81             int connfd = accept( listenfd, ( struct sockaddr* )&client_address, &client_addrlength );
 82             addfd( epollfd, connfd, 1 );
 83         }
 84         else if ( events[i].events & EPOLLIN )
 85         {
 86             printf( "event trigger once\n" );
 87             while( 1 )
 88             {
 89                 memset( buf, \0, BUFFER_SIZE );
 90                 int ret = recv( sockfd, buf, BUFFER_SIZE-1, 0 );
 91                 if( ret < 0 )
 92                 {
 93                     if( ( errno == EAGAIN ) || ( errno == EWOULDBLOCK ) )
 94                     {
 95                         printf( "read later\n" );
 96                         break;
 97                     }
 98                     close( sockfd );
 99                     break;
100                 }
101                 else if( ret == 0 )
102                 {
103                     close( sockfd );
104                 }
105                 else
106                 { 
107                     
108              printf( "get %d bytes of content: %s\n", ret, buf );
109                     
110                 }
111             }
112         }
113         else
114         {
115             printf( "something else happened \n" );
116         }
117     }
118 }
119 
120 int main( int argc, char* argv[] )
121 {
122     if( argc <= 2 )
123     {
124         printf( "usage: %s ip_address port_number\n", basename( argv[0] ) );
125         return 1;
126     }
127     const char* ip = argv[1];
128     int port = atoi( argv[2] );
129 
130     int ret = 0;
131     struct sockaddr_in address;
132     bzero( &address, sizeof( address ) );
133     address.sin_family = AF_INET;
134     inet_pton( AF_INET, ip, &address.sin_addr );
135     address.sin_port = htons( port );
136 
137     int listenfd = socket( PF_INET, SOCK_STREAM, 0 );
138     assert( listenfd >= 0 );
139 
140     ret = bind( listenfd, ( struct sockaddr* )&address, sizeof( address ) );
141     assert( ret != -1 );
142 
143     ret = listen( listenfd, 5 );
144     assert( ret != -1 );
145 
146     struct epoll_event events[MAX_EVENT_NUMBER];
147     int epollfd = epoll_create( 5 );
148     assert( epollfd != -1 );
149     addfd(epollfd,listenfd,1);
150 
151     while( 1 )
152     {
153         int ret = epoll_wait( epollfd, events, MAX_EVENT_NUMBER, -1 );
154         if (ret < 0)
155         {
156             printf( "epoll failure\n" );
157             break;
158         }
159     
160         // lt( events, ret, epollfd, listenfd );
161        et( events, ret, epollfd, listenfd );
162     }
163 
164     close( listenfd );
165     return 0;
166 }

技术分享

 

技术分享

但是奇怪的是为什么总是接受的数据多两个呢?而且

我观察上面的代码,第90行int ret = recv( sockfd, buf, BUFFER_SIZE-1, 0 ),至第108行 printf( "get %d bytes of content: %s\n", ret, buf );

可以看出估计是把enter键包含进去了,所以多出两个字节!

上面是以ET模式在运行,下来我们用LT模式来执行

技术分享

LT和ET模式

标签:

原文地址:http://www.cnblogs.com/leijiangtao/p/4454126.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!