博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
封装类Select I/O模型反弹方式的class封装
阅读量:6351 次
发布时间:2019-06-22

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

新手发帖,很多方面都是刚入门,有错误的地方请大家见谅,欢迎批评指正

    基于select的I/O模型的封装,采取反弹模式,网络上有很多关于select封装,也与本文的相似,本文只是按照自己的习惯封装了一个类,方便使用.

// SrvSelect.h // By LengF 20130506#include 
using 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欢迎交流,同时我也会在平时的应用中实时更新发明的问题.

文章结束给大家分享下程序员的一些笑话语录: 古鸽是一种搜索隐禽,在中国快绝迹了…初步的研究表明,古鸽的离去,很可能导致另一种长着熊爪,酷似古鸽,却又习性不同的猛禽类——犤毒鸟

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

你可能感兴趣的文章
java B2B2C Springcloud电子商城系统—Feign实例
查看>>
java B2B2C Springcloud多租户电子商城系统 (五)springboot整合 beatlsql
查看>>
Throwable是一个怎样的类?
查看>>
三条代码 搞定 python 生成验证码
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
无线和有线路由哪种性能更好
查看>>
Dwr3.0纯注解(纯Java Code配置)配置与应用浅析三之后端反向调用前端
查看>>
Ubuntu下安装遨游浏览器
查看>>
自定义Linux service脚本
查看>>
微信开发之发红包
查看>>
一键lnmp脚本&&php扩展模块安装(适用于CENTOS6.X系列)
查看>>
二维观察---文字的裁剪
查看>>
矩形覆盖
查看>>
ICMP
查看>>
界面设计模式(第2版)(全彩)
查看>>
解决VMware Workstation错误:未能锁定文件
查看>>
CentOS6 手动编译升级 gcc
查看>>
memcached的安装与开启脚本
查看>>
zabbix 邮件报警 -- sendmail
查看>>