博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
LT和ET模式
阅读量:6180 次
发布时间:2019-06-21

本文共 5651 字,大约阅读时间需要 18 分钟。

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 #include
13 #include
14 #include
15 #include
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 else106 { 107 108 printf( "get %d bytes of content: %s\n", ret, buf );109 110 }111 }112 }113 else114 {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 }

首先输入telnet 192,168.255.129登录到服务器后,然后再输入telnet 192.168.255.129 4444

 

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

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

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

我们来测试下是否是我猜测的那样,下来验证下:

将62行的代码修改为如下:

else

{
for(i=0;i<ret;i++)
printf( "get %d bytes of content: %d\n", i, buf[i] );
}

 

[root@linux Desktop]# gcc 9-3mtlt.c -std=gnu99[root@linux Desktop]# ./a.out 192.168.255.129 4444event trigger onceget 0 bytes of content: 49get 1 bytes of content: 50get 2 bytes of content: 51get 3 bytes of content: 13get 4 bytes of content: 10event trigger onceget 0 bytes of content: 49get 1 bytes of content: 50get 2 bytes of content: 51get 3 bytes of content: 52get 4 bytes of content: 53get 5 bytes of content: 54get 6 bytes of content: 55get 7 bytes of content: 56get 8 bytes of content: 57event trigger onceget 0 bytes of content: 49get 1 bytes of content: 50get 2 bytes of content: 51get 3 bytes of content: 13get 4 bytes of content: 10
View Code
[root@linux ~]# telnet 192.168.255.129 4444Trying 192.168.255.129...Connected to 192.168.255.129.Escape character is '^]'.123123456789123
View Code

 

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

当我们关闭服务器后,再重启可能出现如图这样的情况,我们可以在等下大概2分钟,这是因为连接还没完全释放!

前言

在文本处理中,(CarriageReturn),(LineFeed),CR/LF是不同操作系统上使用的换行符,具体如下:

  • Dos和Windows采用回车+换行CR/LF表示下一行
  • 而UNIX/Linux采用换行符LF表示下一行
  • 苹果机(MAC OS系统)则采用回车符CR表示下一行

区别

CR与LF区别如下:

  • CR用符号r表示,十进制ASCII代码是13,十六进制代码为0x0D
  • LF使用n符号表示,ASCII代码是10,十六制为0x0A

所以Windows平台上换行在文本文件中是使用0d 0a两个字节表示,而UNIX和苹果平台上换行则是使用0a0d一个字节表示。

问题

一般操作系统上的运行库会自动决定文本文件的换行格式。如一个程序在Windows上运行就生成CR/LF换行格式的文本文件,而在Linux上运行就生成LF格式换行的文本文件。在一个平台上使用另一种换行符的文件文件可能会带来意想不到的问题,特别是在编辑程序代码时。有时候代码在编辑器中显示正常,但在编辑时却会因为换行符问题而出错。很多文本/代码编辑器带有换行符转换功能,使用这个功能可以将文本文件中的换行符在不同格式单互换。

在不同平台间使用FTP软件传送文件时,在ASCII文本模式传输模式下,一些FTP客户端程序会自动对换行格式进行转换。经过这种传输的文件字节数可能会发生变化。如果你不想FTP修改原文件,可以使用bin模式(二进制模式)传输文本。

转载地址:http://rbafa.baihongyu.com/

你可能感兴趣的文章
Android开发之自定义对话框
查看>>
微信Access Token 缓存方法
查看>>
Eclipsed的SVN插件不能识别之前工作空间的项目
查看>>
Linux 查看iptables状态-重启
查看>>
amazeui学习笔记一(开始使用2)--布局示例layouts
查看>>
c#中lock的使用(用于预约超出限额的流程)
查看>>
ODI基于源表时间戳字段获取增量数据
查看>>
并发容器之CopyOnWriteArrayList(转载)
查看>>
什么是AAC音频格式 AAC-LC 和 AAC-HE的区别是什么
查看>>
原创:goldengate从11.2升级到12.1.2
查看>>
Quartz
查看>>
正则表达式的语法规则
查看>>
C#一个关于委托和事件通俗易懂的例子
查看>>
类似于SVN的文档内容差异对比工具winmerge
查看>>
Cause: java.sql.SQLException: The user specified as a definer ('root'@'%') does not exist
查看>>
quratz线程
查看>>
execnet: rapid multi-Python deployment
查看>>
windows修改3389端口
查看>>
关于JavaScript词法
查看>>
FreeSwitch中的会议功能(4)
查看>>