Linux high performance:http请求的读取和分析
来源:互联网 发布:ai软件mac破解版 编辑:程序博客网 时间:2024/05/29 11:50
#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <assert.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <errno.h>#include <string.h>#include <fcntl.h>#define BUFFER_SIZE 4096enum CHECK_STATE { CHECK_STATE_REQUESTLINE = 0, CHECK_STATE_HEADER, CHECK_STATE_CONTENT };enum LINE_STATUS { LINE_OK = 0, LINE_BAD, LINE_OPEN };enum HTTP_CODE { NO_REQUEST, GET_REQUEST, BAD_REQUEST, FORBIDDEN_REQUEST, INTERNAL_ERROR, CLOSED_CONNECTION };static const char* szret[] = { "I get a correct result\n", "Something wrong\n" };LINE_STATUS parse_line( char* buffer, int& checked_index, int& read_index ){ char temp; for ( ; checked_index < read_index; ++checked_index ) { temp = buffer[ checked_index ]; if ( temp == '\r' ) { if ( ( checked_index + 1 ) == read_index ) { return LINE_OPEN; } else if ( buffer[ checked_index + 1 ] == '\n' ) { buffer[ checked_index++ ] = '\0'; buffer[ checked_index++ ] = '\0'; return LINE_OK; } return LINE_BAD; } else if( temp == '\n' ) { if( ( checked_index > 1 ) && buffer[ checked_index - 1 ] == '\r' ) { buffer[ checked_index-1 ] = '\0'; buffer[ checked_index++ ] = '\0'; return LINE_OK; } return LINE_BAD; } } return LINE_OPEN;}HTTP_CODE parse_requestline( char* szTemp, CHECK_STATE& checkstate ){ char* szURL = strpbrk( szTemp, " \t" ); if ( ! szURL ) { return BAD_REQUEST; } *szURL++ = '\0'; char* szMethod = szTemp; if ( strcasecmp( szMethod, "GET" ) == 0 ) { printf( "The request method is GET\n" ); } else { return BAD_REQUEST; } szURL += strspn( szURL, " \t" ); char* szVersion = strpbrk( szURL, " \t" ); if ( ! szVersion ) { return BAD_REQUEST; } *szVersion++ = '\0'; szVersion += strspn( szVersion, " \t" ); if ( strcasecmp( szVersion, "HTTP/1.1" ) != 0 ) { return BAD_REQUEST; } if ( strncasecmp( szURL, "http://", 7 ) == 0 ) { szURL += 7; szURL = strchr( szURL, '/' ); } if ( ! szURL || szURL[ 0 ] != '/' ) { return BAD_REQUEST; } //URLDecode( szURL ); printf( "The request URL is: %s\n", szURL ); checkstate = CHECK_STATE_HEADER; return NO_REQUEST;}HTTP_CODE parse_headers( char* szTemp ){ if ( szTemp[ 0 ] == '\0' ) { return GET_REQUEST; } else if ( strncasecmp( szTemp, "Host:", 5 ) == 0 ) { szTemp += 5; szTemp += strspn( szTemp, " \t" ); printf( "the request host is: %s\n", szTemp ); } else { printf( "I can not handle this header\n" ); } return NO_REQUEST;}HTTP_CODE parse_content( char* buffer, int& checked_index, CHECK_STATE& checkstate, int& read_index, int& start_line ){ LINE_STATUS linestatus = LINE_OK; HTTP_CODE retcode = NO_REQUEST; while( ( linestatus = <span style="font-size:24px;color:#FF0000;">parse_line</span>( buffer, checked_index, read_index ) ) == LINE_OK )//解析出一行的内容 { char* szTemp = buffer + start_line; start_line = checked_index; switch ( checkstate ) { case CHECK_STATE_REQUESTLINE: { retcode = <span style="font-size:24px;color:#FF0000;">parse_requestline</span>( temp, checkstate );//分析请求行 if ( retcode == BAD_REQUEST ) { return BAD_REQUEST; } break; } case CHECK_STATE_HEADER: { retcode = <span style="font-size:24px;color:#FF0000;">parse_headers</span>( temp );//分析头部字段 if ( retcode == BAD_REQUEST ) { return BAD_REQUEST; } else if ( retcode == GET_REQUEST ) { return GET_REQUEST; } break; } default: { return INTERNAL_ERROR; } } } if( linestatus == LINE_OPEN ) { return NO_REQUEST; } else { return BAD_REQUEST; }}int main( int argc, char* argv[] ){ if( argc <= 2 ) { printf( "usage: %s ip_address port_number\n", basename( argv[0] ) ); return 1; } const char* ip = argv[1]; int port = atoi( argv[2] ); struct sockaddr_in address; bzero( &address, sizeof( address ) ); address.sin_family = AF_INET; inet_pton( AF_INET, ip, &address.sin_addr ); address.sin_port = htons( port ); int listenfd = socket( PF_INET, SOCK_STREAM, 0 ); assert( listenfd >= 0 ); int ret = bind( listenfd, ( struct sockaddr* )&address, sizeof( address ) ); assert( ret != -1 ); ret = listen( listenfd, 5 ); assert( ret != -1 ); struct sockaddr_in client_address; socklen_t client_addrlength = sizeof( client_address ); int fd = accept( listenfd, ( struct sockaddr* )&client_address, &client_addrlength ); if( fd < 0 ) { printf( "errno is: %d\n", errno ); } else { char buffer[ BUFFER_SIZE ]; memset( buffer, '\0', BUFFER_SIZE ); int data_read = 0; int read_index = 0; int checked_index = 0; int start_line = 0; CHECK_STATE checkstate = CHECK_STATE_REQUESTLINE; while( 1 ) { data_read = recv( fd, buffer + read_index, BUFFER_SIZE - read_index, 0 ); if ( data_read == -1 ) { printf( "reading failed\n" ); break; } else if ( data_read == 0 ) { printf( "remote client has closed the connection\n" ); break; } read_index += data_read; //分析目前已经获得的所有客户数据 //buffer表示缓冲区,checked_index表示当前已分析多少字节的客户数据,cheeckstate主状态机的初始状态,read_index表示buffer中已读字节数,start_line表示当前分析到哪一行 HTTP_CODE result = <span style="font-size:24px;color:#FF0000;">parse_content</span>( buffer, checked_index, checkstate, read_index, start_line ); if( result == NO_REQUEST ) { continue; } else if( result == GET_REQUEST ) { send( fd, szret[0], strlen( szret[0] ), 0 ); break; } else { send( fd, szret[1], strlen( szret[1] ), 0 ); break; } } close( fd ); } close( listenfd ); return 0;}</span>
0 0
- Linux high performance:http请求的读取和分析
- linux网络编程十二:简单模拟HTTP请求的读取和分析
- High performance
- [High.Performance.MySQL(3rd,2012.3)].Baron.Schwartz.之分析工具的使用
- Http请求和响应分析
- HPCC(High Performance Computing Challenge)的输出
- 《High Performance JavaScript》的一些摘要1
- 《High Performance JavaScript》的一些摘要2
- 《High Performance JavaScript》的一些摘要3
- 一次HTTP请求的分析
- http 的Get和 Post请求深入分析
- http Form表单的Get和 Post请求深入分析
- HttpServletRequest中读取HTTP请求的body
- Linux Performance Analysis and Tools(Linux性能分析和工具)
- Linux Performance Analysis and Tools(Linux性能分析和工具)
- Linux Performance Analysis and Tools(Linux性能分析和工具)
- Linux Performance Analysis and Tools(Linux性能分析和工具)
- High Performance Linux Clusters with OSCAR, Rocks, OpenMosix, and MPI
- Vc++ 网络编程
- uva 10404 - Bachet's Game(dp)
- cocos2dx lua 添加动画
- document.ready和onload的区别----JavaScript文档加载完成事件
- Any CPU,x86,x64
- Linux high performance:http请求的读取和分析
- NSString的比较方法,开始我准备使用NSPredicate的
- Android 内存溢出解决方案(OOM) 整理总结
- ext2和ext3文件系统
- Raphael.js API之Raphael.svg(),Element.paper,Element.pause(),Raphael.pathBBox(),Raphael.st,Raphael.el
- svn服务端及客户端搭建(WINDOWS)
- 1、C语言100个经典算法(一)
- C++ 启示录
- C++中的static关键字