字节型TCP协议解析
2015-08-27 02:35
633 查看
#include <stdio.h> #include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #include <unistd.h> #include <netinet/in.h> #include <arpa/inet.h> #include <error.h> #include <errno.h> #include <string> #include <list> #define DEBUGS inline char* memstr(void *buf , int size , void * need , int needsize) { char *p=(char*) buf; int index = 0 ; while(index < size) { if((size-index) < needsize ) { return NULL; } if( memcmp(p,need,needsize) == 0 ) //find the right buffer(need) { // printf("find,index=%d\n",index); return p; } else { ++p; index++; } } return NULL; } class BaseHandler { public: BaseHandler() {} virtual ~BaseHandler() {} public: virtual int hander( void * data , int size ) =0; void config(const char *p ) { strFileName= p; } protected : std::string strFileName ; }; class MagReader :public BaseHandler { public: typedef struct _msg_data_ { void *p; int size ; _msg_data_( void * a , int b ) { p =malloc(b); memcpy(p , a , b ) ; size = b ; } ~_msg_data_() { if(p) free(p); } }MSG,*P_MSG; public: MagReader() {} ~MagReader() { for( std::list<P_MSG>::iterator it =m_list.begin() ; it!=m_list.end() ;it++ ) { delete (*it) ; } } public: int hander( void * data , int size ) { P_MSG buf = new MSG( data ,size ) ; m_list.push_back(buf); #ifdef DEBUGS char *p_=(char*)data ; for( int i = 0 ; i < size ; i++) { printf("%c" , p_[i]) ; } printf("\n") ; #endif } private: std::list<P_MSG> m_list ; }; class FileWriter:public BaseHandler { public: FileWriter():fp(NULL) , bopened(false) { } ~FileWriter() { if(fp) { fclose(fp) ; fp = NULL ; bopened = false ; } } public: int hander( void * data , int size ) { if(bopened) { this->write(data, size ) ; } else { this->open(strFileName.c_str() ) ; this->write(data, size ) ; } } public: const int open(const char * filename) { fp=fopen(filename,"w+") ; bopened=true; } const int write( void * buffer , int buffer_size = 1 ) { fwrite(buffer , buffer_size , 1 ,fp ) ; return 0; } private: FILE *fp; bool bopened; }; class Factory { public: static BaseHandler* object( int type ) { switch(type) { case 0: return new MagReader(); break; case 1: return new FileWriter(); break; default: break; } return NULL ; } }; typedef int socket_t ; class FileTransport { private: FileTransport(); ~FileTransport(); public: static FileTransport* instance(); static void release() ; public: const int Init( char *Server 4000 IP, int Serverport ) ; const int OpenCusor( char *mesh , char*sql) ; const int Fetch( ) ; const int Fetch2( ) ; const int Fetch3( ) ; void Close() ; void setfile(const char * p) ; private: socket_t fd ; static FileTransport* m_pFileTransport ; BaseHandler* handler; std::string strFileName ; } ; FileTransport* FileTransport::m_pFileTransport=NULL; FileTransport::FileTransport() { fd = socket(AF_INET,SOCK_STREAM,0); handler = NULL ; } FileTransport::~FileTransport() { this->Close() ; if(handler) { delete handler; handler=NULL; } } void FileTransport::setfile(const char * p) { strFileName=p; } FileTransport* FileTransport::instance() { if(m_pFileTransport == NULL ) { m_pFileTransport=new FileTransport(); } return m_pFileTransport; } void FileTransport::release() { if(m_pFileTransport) { delete m_pFileTransport ; } } //连接服务器 const int FileTransport::Init( char *ServerIP, int Serverport ) { struct sockaddr_in address; address.sin_family = AF_INET; address.sin_addr.s_addr = inet_addr(ServerIP); address.sin_port = htons(Serverport); int uiLen = sizeof(address); int ret = connect( fd ,(struct sockaddr *)&address,uiLen ); if(ret != 0 ) { printf("connect failed") ; return -1; } } void FileTransport::Close() { ::close(fd); } const int FileTransport::OpenCusor( char *mesh , char*sql) { char ch[1024] = {0}; char *p = ch ; strcpy( p, mesh ) ; p+= strlen(mesh) ; strcpy( p," " ) ; p+= 1 ; strcpy( p,sql ) ; int idatasize = strlen(ch); printf("data is [%s],size=%d\n",ch,idatasize ) ; ::send(fd,&idatasize,sizeof(int) , 0 ) ; ::send(fd,ch,idatasize ,0); char chm ={0}; ::recv( fd , &chm , 1 , 0 ) ; printf("chm=%d\n" , chm ) ; } //provide a method to prevent tcp pollution. //the process hanged up to wait the timing when the Protocol_Header is found in the // recv tcp streams . // in anthor words , if the process is waked up , means that recv the right character //we wanted . by the way , continue to handler the next stream is allowed . #if 1 const int FileTransport::Fetch3( ) { #define Protocol_Header 0xFDF4 #define Protocol_Tail 0xFDF5 #define ReadIOCacheSize 2 /***不需要字节对齐***/ #pragma pack(1) struct headers { //unsigned int a ; unsigned short head ; unsigned char type; unsigned int length; }; #pragma pack() #pragma pack(1) struct tail { unsigned char check; unsigned short tail; }; #pragma pack() struct headers obj ; memset(&obj, 0x00 ,sizeof(obj) ) ; char *pHead=(char*)malloc( obj.head) ; char *pHead_Walk = pHead ; char *pHead_End = pHead_Walk+(sizeof(obj.head) -1 ) ; while(1) { unsigned char ch; ::recv(fd,&ch,1,0 ) ; if( pHead_Walk < pHead_End ) { memcpy(pHead_Walk , &ch , 1 ) ; ++pHead_Walk; } else// equal { memcpy(pHead_Walk , &ch , 1 ) ; unsigned short s = 0 ; memcpy(&s , pHead , sizeof(s) ) ; if( s == Protocol_Header )//find the right character position { obj.head = s ; break; } else { pHead_Walk=pHead; } } } if(pHead) { free(pHead) ; } printf("start get type and length\n"); char *pBuf = (char*)(&obj) ; pBuf += sizeof(obj.head) ;//skip the head char *pBuf_Walk = pBuf ; int iReadHead_Reset = 0 ; while(iReadHead_Reset<(sizeof(obj) - sizeof(obj.head) )) { char chBuf[ 1024 ] ={0} ; int size = ::recv(fd,chBuf, ( sizeof(obj) - sizeof(obj.head) ) ,0 ) ; memcpy(pBuf_Walk ,chBuf ,size ) ; pBuf_Walk += size ; iReadHead_Reset+=size ; } printf("type=%d, length=%d\n" , obj.type, obj.length ) ; handler = Factory::object(obj.type) ; if(!handler) { printf("tyep[%d] is error\n" , obj.type ) ; return -1; } handler->config(strFileName.c_str()); char buf[ReadIOCacheSize]={0}; int bufreaded = 0 ; /*查找匹配的正文.每次读取当前剩余的字节数与ReadIOCacheSize的最小值*/ do { int sizeEach=(ReadIOCacheSize>( obj.length -bufreaded ) )?( ( obj.length -bufreaded ) ):(ReadIOCacheSize); memset(buf,0x00 ,sizeof(buf) ) ; int ret = recv( fd , buf , sizeEach , 0 ) ; #ifdef WIN32 if(ret == SOCKET_ERROR) { return -1; } #else if(ret == EAGAIN) { return -1; } #endif bufreaded+=ret; handler->hander(buf ,ret ) ; printf("[%d receieved]%s\n",ret,buf) ; }while(bufreaded < obj.length ) ; //检查包的结尾 struct tail otail; memset( &otail , 0x00 , sizeof(otail) ) ; char *ptail = (char*)&otail ; char *otail_Walk = ptail ; int inReadTail = 0 ; while( inReadTail < sizeof(otail) ) { char tmp[sizeof(otail) ] = {0} ; int ret = ::recv(fd,tmp,sizeof(otail),0); #ifdef WIN32 if(ret == SOCKET_ERROR) { return -1; } #else if(ret == EAGAIN) { return -1; } #endif memcpy(otail_Walk,tmp ,ret ) ; inReadTail+=ret; otail_Walk+=ret; } #if 0 char tmp[1024] = {0} ; while(1) { memset(tmp,0x00 , sizeof(tmp) ) ; int ret = ::recv(fd,tmp,sizeof(otail),0); #ifdef WIN32 if(ret == SOCKET_ERROR) { return -1; } #else if(ret == EAGAIN) { return -1; } #endif if(ret == sizeof(otail)) { break ; } else { continue ; } } memcpy(&otail , tmp , sizeof(otail) ) ; #endif printf("tail=%d\n" , otail.tail) ; if( otail.tail != Protocol_Tail ) { printf("receive error tail[%d]\n" ,otail.tail ) ; sleep(10000) ; return -1; } return 0; //......... } #endif const int FileTransport::Fetch2( ) { #define Protocol_Header 0xFDF4 #define Protocol_Tail 0xFDF5 #define ReadIOCacheSize 2 /***不需要字节对齐***/ #pragma pack(1) struct headers { //unsigned int a ; unsigned short head ; unsigned char type; unsigned int length; }; #pr d507 agma pack() #pragma pack(1) struct tail { unsigned char check; unsigned short tail; }; #pragma pack() /*查找匹配的头*/ struct headers oheaders; memset(&oheaders,0x00,sizeof(oheaders) ) ; printf("sizeof struct headers = %d\n" , sizeof( oheaders ) ); while(1) { char ch[1024]={0} ; int ret = recv(fd,ch,sizeof(oheaders),0); if(ret == 0 ) { printf("server has close this session\n" ) ; return -1; } #ifdef WIN32 if(ret == SOCKET_ERROR) { return -1; } #else if(ret == EAGAIN) { return -1; } #endif printf("recv size=%d\n" , ret) ; memcpy(&oheaders,ch , sizeof(oheaders)); printf("oheaders.type=%d,oheaders.head=%d,oheaders.length=%d\n",oheaders.type,oheaders.head,oheaders.length); if(oheaders.head==Protocol_Header) { break; } else { printf("receive error head\n") ; return -1; } } /***在这里根据type选择创建的类型 0Msg文言 1 文件输出***/ handler = Factory::object(oheaders.type) ; if(!handler) { printf("tyep[%d] is error\n" , oheaders.type ) ; return -1; } handler->config(strFileName.c_str()); char buf[ReadIOCacheSize]={0}; int bufreaded = 0 ; /*查找匹配的正文.每次读取当前剩余的字节数与ReadIOCacheSize的最小值*/ do { int sizeEach=(ReadIOCacheSize>( oheaders.length -bufreaded ) )?( ( oheaders.length -bufreaded ) ):(ReadIOCacheSize); memset(buf,0x00 ,sizeof(buf) ) ; int ret = recv( fd , buf , sizeEach , 0 ) ; #ifdef WIN32 if(ret == SOCKET_ERROR) { return -1; } #else if(ret == EAGAIN) { return -1; } #endif bufreaded+=ret; handler->hander(buf ,ret ) ; //printf("[%d receieved]%s\n",ret,buf) ; }while(bufreaded < oheaders.length ) ; //检查包的结尾 struct tail otail; memset( &otail , 0x00 , sizeof(otail) ) ; char tmp[1024] = {0} ; recv(fd,tmp,sizeof(otail),0); memcpy(&otail , tmp , sizeof(otail) ) ; printf("tail=%d\n" , otail.tail) ; if( otail.tail != Protocol_Tail ) { printf("receive error tail\n") ; return -1; } } int main( int argc ,char ** argv) { FileTransport*p = FileTransport::instance(); p->setfile(argv[3]); p->Init(argv[1] ,atoi(argv[2]) ) ; p->OpenCusor("1122222" ,"select * from aaaaaaa" ) ; int i = p->Fetch3(); return i ; }
相关文章推荐
- scrapy 爬取https网页时出现ssl错误
- Android HTTP session && cookie
- Android 通过httpclient请求web服务器,并解决用户登录session保持
- Http Basic Authentication 的请求头Authorization的状态保存问题:见‘斜粗下划线’部分说明
- Http Basic Authentication has some limitations, maybe nginx could do some help...
- ub 网络框架的几种线程模型
- PostgreSQL之网络地址类型
- 网络配置
- Httpd运维日志:通过apxs添加模块
- 2015年8月15-16日,杨学明老师《互联网行业市场管理与产品规划》内训在中国科学院互联网络信息中心成功举办!
- HelloX操作系统网络功能简介及使用和开发指南
- HelloX操作系统网络功能简介及使用和开发指南
- TCP实现P2P通信、TCP穿越NAT的方法、TCP打洞
- TCP/IP
- C# httpwebrequest访问HTTPS错误处理
- TCP/IP详解-坚持定时器和保活定时器
- Kids and Prizes 来源: <http://acm.hust.edu.cn/vjudge/contest/view.action?cid=85996#problem/B>
- HttpClient4.3教程
- 《HTTP权威指南》阅读笔记(九)
- 深度学习记录第一天--神经网络