新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正
基于select的I/O模型的封装,采取反弹模式,网络上有很多关于select封装,也与本文的相似,本文只是按照自己的习惯封装了一个类,方便使用.
// SrvSelect.h // By LengF 20130506#includeusing namespace std;#define SOCKET_TIMEOUT -100class CSrvSelect {public: CSrvSelect(); virtual ~CSrvSelect();public: SOCKET StartConnect(string szHost,UINT nPort); int SrvRecv(SOCKET s, char *buf, int len, int flag , int overtime,char*EndMark,BOOL soonflag=FALSE); int SrvSend(SOCKET s, const char *buf, int len, int flag,int overtime); void ErrorPrint(LPCTSTR lpOutputString );public: SOCKET m_socket; BOOL m_bError;};
上面实现类函数和各种初始化:
每日一道理 坚持的昨天叫立足,坚持的今天叫进取,坚持的明天叫成功。
// SrvSelect.cpp: implementation of the CSrvSelect class.////#include "stdafx.h"#include "SrvSelect.h"//// Construction/Destruction//CSrvSelect::CSrvSelect(){ // Init Socket Library WSADATA wsa; WSAStartup(MAKEWORD(2,2),&wsa); // Data Init m_socket = INVALID_SOCKET; m_bError = TRUE; // Debug Mode}CSrvSelect::~CSrvSelect(){ if (m_socket != INVALID_SOCKET) { closesocket(m_socket); shutdown(m_socket,2); m_socket = INVALID_SOCKET; } WSACleanup();}void CSrvSelect::ErrorPrint(LPCTSTR lpOutputString){ if (m_bError) { printf("%s\n",lpOutputString); //OutputDebugString(lpOutputString); }}SOCKET CSrvSelect::StartConnect(string szHost, UINT nPort){ SOCKET s = INVALID_SOCKET; SOCKADDR_IN ClientAddr; LPHOSTENT Host; // for DNS memset(&ClientAddr,0,sizeof(SOCKADDR_IN)); if (szHost.empty() || nPort ==0) // Params Error return INVALID_SOCKET; Host=gethostbyname(szHost.c_str()); ClientAddr.sin_family = AF_INET; ClientAddr.sin_port = htons((u_short)nPort); // Host Port ClientAddr.sin_addr = *((LPIN_ADDR)*Host->h_addr_list); // Host IP // create socket // PF_INET for IPV6,IPV4 s = socket(PF_INET,SOCK_STREAM,0); if(connect(s,(LPSOCKADDR)&ClientAddr,sizeof(ClientAddr)) == SOCKET_ERROR) // connect error { ErrorPrint("[s] Connect Error."); closesocket(s); shutdown(s,2); s = INVALID_SOCKET; } m_socket = s; return s;}int CSrvSelect::SrvSend(SOCKET s, const char *buf, int len, int flag, int overtime){ int ret; int nLeft = len; int idx = 0; fd_set readfds; struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 500; DWORD s_time = GetTickCount(); while ( nLeft > 0 ) { MSG msg; PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ; if(msg.message == WM_QUIT) return 0; FD_ZERO( &readfds ); FD_SET( s , &readfds ); int errorret = select( 0 , NULL, &readfds, NULL , &timeout ); if( errorret == SOCKET_ERROR ) { ErrorPrint("[s] Socket select error."); return SOCKET_ERROR; } DWORD e_time = GetTickCount( ); if ( !FD_ISSET( s , &readfds ) ) { if( e_time - s_time > overtime*1000 ) { ErrorPrint("[s] Send Data TimeOut."); return 0; } else { continue; } } ret = send( s, &buf[idx], nLeft, flag ); if ( ret <= 0 ) { return ret; } nLeft -= ret; idx += ret; } // end while return len;}int CSrvSelect::SrvRecv(SOCKET s, char *buf, int len, int flag, int overtime, char *EndMark, BOOL soonflag){ int ret; int nLeft = len; int idx = 0; int nCount = 0; fd_set readfds; struct timeval timeout; timeout.tv_sec = 0; timeout.tv_usec = 500; DWORD s_time = GetTickCount(); while ( nLeft > 0 ) { MSG msg; PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) ; if(msg.message == WM_QUIT) return 0; FD_ZERO( &readfds ); FD_SET( s , &readfds ); if( select( 0 , &readfds , NULL , NULL , &timeout ) == SOCKET_ERROR ) { return SOCKET_ERROR; } DWORD e_time = GetTickCount( ); if ( !FD_ISSET( s , &readfds ) ) { if( e_time - s_time > overtime*1000 ) return SOCKET_TIMEOUT; else continue; } ret = recv( s, &buf[idx], nLeft, flag ); if( soonflag == TRUE ) { return ret; } s_time = e_time ; // reset time if ( ret <= 0 ) { int LastError = GetLastError(); if ( ( -1 == ret ) && ( WSAETIMEDOUT == LastError ) ) continue; if ( ( -1 == ret ) && ( WSAEWOULDBLOCK == LastError ) ) { if ( nCount < 2000 ) { Sleep( 10 ); nCount++; continue; } } return ret; } nCount = 0; nLeft -= ret; idx += ret; if( EndMark != NULL && idx>5) { if( strstr(buf+(idx-5),EndMark) != NULL ) { break; } } }// end while return idx;}
至此全部类的封装已经完成了.如果有什么想法,或者BUGS欢迎交流,同时我也会在平时的应用中实时更新发明的问题.
文章结束给大家分享下程序员的一些笑话语录: 古鸽是一种搜索隐禽,在中国快绝迹了…初步的研究表明,古鸽的离去,很可能导致另一种长着熊爪,酷似古鸽,却又习性不同的猛禽类——犤毒鸟