www.pudn.com > 2003090514065121890.zip > spIPCComm.cpp


#include "stdafx.h" 
//修改了对WinSock.h的包含文件为Winsock2.h 
#include "spIPCComm.h" 
 
using namespace commIPC; 
/* 
 
通讯类,by wenyy 2002-02-01 
封装了通信类的读写操作,(类不是线程安全的) 
v.01 支持Socket 
v.02 支持NamedPipe 
通信类中主要封装了通信读写操作 
所有类功能的说明见CIPCComm定义 
v.01 socket communication 
 
2002-06-25 
by wenyy 
将文件编译成为DLL 形式 
同时引出相关的全局函数 
 
2003-01-22 
by wenyy 
修改TestAndRecv的无法检测网络段开的错误 
 
*/ 
extern "C" SOCKET SPCreateUDPSocket(int iLocalPort,LPCSTR pszLocalAddr) 
{ 
	SOCKET sock = socket(AF_INET,SOCK_DGRAM,0); 
	if(sock == INVALID_SOCKET) 
		return INVALID_SOCKET ; 
	//bind 
	SOCKADDR_IN sinLocal; 
	sinLocal.sin_family=AF_INET; 
	sinLocal.sin_port=htons(iLocalPort); 
	if(pszLocalAddr ) 
	{ 
		LONG lAddr= inet_addr(pszLocalAddr); 
		memcpy((LPSTR)&(sinLocal.sin_addr),&lAddr,sizeof(lAddr)); 
	} 
	else 
	{ 
		LONG lAddr= INADDR_ANY; 
		memcpy(&(sinLocal.sin_addr),&lAddr,sizeof(lAddr)); 
	} 
	int iStatus=bind(sock,(struct sockaddr FAR*)&sinLocal,sizeof(sinLocal)); 
 
	if(iStatus==SOCKET_ERROR) 
	{ 
		closesocket(sock); 
		return INVALID_SOCKET ; 
	} 
    
	return sock; 
} 
 
extern "C" SOCKET SPCreateConnectSocket(LPCSTR pszRemoteAddr,int iPort,LPCSTR pszLocalAddr) 
{ 
	SOCKET sock=socket(AF_INET,SOCK_STREAM,0); 
	if(sock == INVALID_SOCKET) 
		return INVALID_SOCKET ; 
 
	//connect 
	SOCKADDR_IN sinRemote; 
	sinRemote.sin_family=AF_INET; 
	sinRemote.sin_port=htons(iPort); 
	LONG lAddr= inet_addr(pszRemoteAddr); 
	memcpy((LPSTR)&(sinRemote.sin_addr),&lAddr,sizeof(lAddr)); 
	int iStatus = connect(sock,(struct sockaddr FAR*)&sinRemote,sizeof(sinRemote)); 
	if(iStatus == SOCKET_ERROR) 
	{ 
		closesocket(sock); 
		return INVALID_SOCKET ; 
	} 
	return sock; 
} 
 
extern "C" SOCKET SPCreateAcceptSocket(SOCKET sockListen,char* pszHost,int *piPort) 
{ 
	SOCKADDR_IN sinRemote; 
	int iLen=sizeof(sinRemote); 
	SOCKET sComm = accept(sockListen,(struct sockaddr *)&sinRemote,&iLen); 
	if(sComm != INVALID_SOCKET) 
	{ 
		if(pszHost) 
			strcpy(pszHost,inet_ntoa(sinRemote.sin_addr)); 
		if(piPort) 
			*piPort = ntohs(sinRemote.sin_port); 
	} 
	return sComm; 
} 
 
extern "C" SOCKET SPCreateListenSocket(LPCSTR pszLocalAddr,UINT uPort) 
{ 
	SOCKET sock=socket(AF_INET,SOCK_STREAM,0); 
	if(sock==INVALID_SOCKET) 
		return INVALID_SOCKET ; 
	//bind 
	SOCKADDR_IN sinLocal; 
	sinLocal.sin_family=AF_INET; 
	sinLocal.sin_port=htons(uPort); 
	if(pszLocalAddr ) 
	{ 
		LONG lAddr= inet_addr(pszLocalAddr); 
		memcpy((LPSTR)&(sinLocal.sin_addr),&lAddr,sizeof(lAddr)); 
	} 
	else 
	{ 
		LONG lAddr= INADDR_ANY; 
		memcpy(&(sinLocal.sin_addr),&lAddr,sizeof(lAddr)); 
	} 
	int iStatus=bind(sock,(struct sockaddr FAR*)&sinLocal,sizeof(sinLocal)); 
 
	if(iStatus==SOCKET_ERROR) 
	{ 
		closesocket(sock); 
		return INVALID_SOCKET ; 
	} 
	iStatus=listen(sock,15); 
	if(SOCKET_ERROR==iStatus) 
	{ 
		closesocket(sock); 
		return INVALID_SOCKET ; 
	} 
	return sock; 
} 
 
///////////////////////////////// 
//  socket implement 
///////////////////////////////// 
CIPCSocket::CIPCSocket(SOCKET sockComm,BOOL fAutoDel) 
{ 
	ASSERT(sockComm !=0); 
	ASSERT(sockComm != INVALID_SOCKET); 
	m_fAutoDel=fAutoDel; 
	m_sockComm = sockComm; 
} 
 
CIPCSocket::~CIPCSocket() 
{ 
	if(m_fAutoDel) 
	{ 
		shutdown(m_sockComm,SD_BOTH); 
		closesocket(m_sockComm); 
	} 
} 
 
int CIPCSocket::Recv(const int iWant,BYTE* pbBuf,int& iRead) 
{ 
	int iRecved=0; 
	iRead = 0; 
	while(1) 
	{ 
		int iLeft = iWant -iRecved; 
		ASSERT(iLeft != 0); 
		int iRet = recv(m_sockComm,(char*)pbBuf+iRecved,iLeft,0); 
		if(iRet ==0 || iRet == SOCKET_ERROR  ) 
			return SP_ERR_NETWORK; 
		iRecved += iRet; 
		iRead = iRecved; 
		if(iRecved == iWant) 
		{ 
			return SP_ERR_SUCCESS; 
		} 
	} 
	return SP_ERR_NETWORK; 
} 
 
int CIPCSocket::Send(const int iWant,const BYTE *pbBuf,int& iWrote) 
{ 
	int iSent=0; 
	iWrote = 0; 
	while(1) 
	{ 
		int iLeft = iWant -iSent; 
		ASSERT(iLeft != 0); 
		int iRet = send(m_sockComm,(char*)pbBuf+iSent,iLeft,0); 
		if(iRet ==0 || iRet == SOCKET_ERROR  ) 
			return SP_ERR_NETWORK; 
		iSent += iRet; 
		iWrote = iSent; 
		if(iSent == iWant) 
			return SP_ERR_SUCCESS; 
	} 
	return SP_ERR_NETWORK; 
} 
 
int CIPCSocket::TestRead(int iTimeOut) 
{ 
	struct timeval tvLeft={iTimeOut,0},tvExp={0,0}; 
	fd_set fdExp; 
	FD_ZERO(&fdExp); 
	FD_SET(m_sockComm,&fdExp); 
	int iRet = select(1,NULL,NULL,&fdExp,&tvExp); 
	switch (iRet) 
	{ 
	case SOCKET_ERROR : 
		return SP_ERR_NETWORK; 
		break; 
	case 1: 
		return SP_ERR_NETWORK; 
		break; 
	} 
 
	fd_set fdRecv; 
	FD_ZERO(&fdRecv); 
	FD_SET(m_sockComm,&fdRecv); 
	iRet = select(1,&fdRecv,NULL,NULL,&tvLeft); 
	switch (iRet) 
	{ 
	case SOCKET_ERROR : 
		return SP_ERR_NETWORK; 
		break; 
	case 0 : 
		return SP_ERR_NODATA; 
		break; 
	case 1: 
		return SP_ERR_SUCCESS; 
		break; 
	default: 
		return SP_ERR_GENERAL; 
		break; 
	} 
} 
int CIPCSocket::TestConnect(int iTimeOut) 
{ 
	return TestRead(iTimeOut); 
	/*struct timeval tvLeft={iTimeOut,0}; 
	fd_set fdRecv; 
	FD_ZERO(&fdRecv); 
	FD_SET(m_sockComm,&fdRecv); 
	int iRet = select(1,&fdRecv,NULL,NULL,&tvLeft); 
	switch (iRet) 
	{ 
	case SOCKET_ERROR : 
		return SP_ERR_NETWORK; 
		break; 
	case 0 : 
		return SP_ERR_NODATA; 
		break; 
	case 1: 
		return SP_ERR_SUCESS; 
		break; 
	default: 
		return SP_ERR_GENERAL; 
		break; 
	}*/ 
} 
 
int CIPCSocket::RecvWithTimeOut(int iTimeout,const int iWant,BYTE* pbBuf,int& iRead) 
{ 
	DWORD dwTick1 = GetTickCount(); 
	int iRecved=0,iLeft = iWant; 
	iRead = 0; 
	while(1) 
	{ 
		int iTest = TestRead(1); 
		if(SP_ERR_SUCCESS == iTest) 
		{ 
			int iRet = recv(m_sockComm,(char*)pbBuf+iRecved,iLeft,0); 
			if(iRet == SOCKET_ERROR ||iRet ==0) 
				return SP_ERR_NETWORK; 
			iRecved += iRet; 
			iRead = iRecved; 
			iLeft = iWant - iRecved; 
		} 
		else if(iTest == SP_ERR_NETWORK) 
			return SP_ERR_NETWORK; 
 
		if(iRead == iWant) 
			return  SP_ERR_SUCCESS; 
 
		DWORD dwTick2= GetTickCount(); 
		if(dwTick2-dwTick1 > (DWORD)iTimeout*1000) 
		{//检查是否超时 
			if (iRead ==0) 
				return SP_ERR_NODATA; 
			else 
				return SP_ERR_NOT_FINISH; 
		} 
	} 
	return SP_ERR_GENERAL; 
} 
 
int CIPCSocket::TestAndRecv(int iTimeout,const int iWant,BYTE* pbBuf,int& iRead) 
{ 
	int iRet = TestRead(iTimeout); 
	iRead = 0; 
	if(iRet == SP_ERR_SUCCESS) 
	{ 
		iRet = recv(m_sockComm,(char*)pbBuf,iWant,0); 
		if(iRet ==SOCKET_ERROR || iRet ==0) 
			return SP_ERR_NETWORK; 
 
		iRead = iRet; 
		if(iRead ==0) 
		{ 
			return SP_ERR_NETWORK; 
			//return SP_ERR_NODATA; by wenyy 2003/01 V3.0 
			//如果检测到有数据但是无法读入表示网络错误 
		} 
		else 
		{ 
			if(iRead == iWant) 
				return SP_ERR_SUCCESS; 
			else 
				return SP_ERR_NOT_FINISH; 
		} 
	} 
	return iRet; 
} 
/////////////////////////////////// 
// UDP implement 
/////////////////////////////////// 
CUDPSocket::CUDPSocket(SOCKET sockComm,BOOL fAutoDel):CIPCSocket(sockComm,fAutoDel) 
{ 
	m_uMaxUDP = 64; 
	int iLen=sizeof(m_uMaxUDP); 
	if(SOCKET_ERROR == getsockopt(sockComm,SOL_SOCKET,SO_MAX_MSG_SIZE,(char*)&m_uMaxUDP,&iLen) ) 
		m_uMaxUDP = 64; 
} 
int CUDPSocket::SendTo(const int iWant,const BYTE* pbBuf,int& iWrote,LPCSTR pszHost,const int iPort) 
{ 
	iWrote = 0; 
//	if(iWant > (int)m_uMaxUDP) 
//		return SP_UDP_TOOLONG; 
	SOCKADDR_IN sinRemote; 
	sinRemote.sin_family=AF_INET; 
	sinRemote.sin_port=htons(iPort); 
	LONG lAddr= inet_addr(pszHost); 
	memcpy((LPSTR)&(sinRemote.sin_addr),&lAddr,sizeof(lAddr)); 
	int iStatus = sendto(m_sockComm,(const char*)pbBuf,iWant,0,(struct sockaddr FAR*)&sinRemote,sizeof(sinRemote)); 
	if(iStatus ==SOCKET_ERROR) 
	{ 
		if(WSAEMSGSIZE == GetLastError()) 
			return SP_UDP_TOOLONG; 
		else 
			return SP_ERR_GENERAL; 
	} 
	iWrote = iStatus; 
	return SP_ERR_SUCCESS; 
 
} 
int CUDPSocket::RecvFrom(const int iWant,const BYTE* pbBuf,int& iRead,char* pszHost,int *piPort) 
{ 
	iRead = 0; 
	SOCKADDR_IN sinRemote; 
	int iLen = sizeof(sinRemote); 
	int iStatus = recvfrom(m_sockComm,(char*)pbBuf,iWant,0,(struct sockaddr FAR*)&sinRemote,&iLen); 
	if(SOCKET_ERROR == iStatus) 
	{ 
		if(WSAEMSGSIZE == GetLastError()) 
			return SP_UDP_SMALLBUF; 
		else 
			return SP_ERR_GENERAL; 
	} 
	iRead = iStatus; 
	if(pszHost) 
		strcpy(pszHost,inet_ntoa(sinRemote.sin_addr)); 
	if(piPort) 
		*piPort = ntohs(sinRemote.sin_port); 
	return SP_ERR_SUCCESS; 
} 
 
///////////////////////////// 
//  named pipe implement 
///////////////////////////// 
extern "C" HANDLE SPCreateServerPipe(LPCSTR pszPipeName,int iTimeout) 
{ 
	ASSERT(iTimeout); 
	HANDLE hP = CreateNamedPipe(pszPipeName,PIPE_ACCESS_DUPLEX, 
								PIPE_TYPE_BYTE|PIPE_WAIT,PIPE_UNLIMITED_INSTANCES, 
								1024,1024, 
								iTimeout*1000,NULL); 
	if( INVALID_HANDLE_VALUE != hP) 
	{ 
		if( ConnectNamedPipe(hP,NULL) ) 
			return hP; 
		else 
			CloseHandle(hP); 
	} 
	return INVALID_HANDLE_VALUE; 
} 
 
extern "C" HANDLE SPCreateClientPipe(LPCSTR pszPipeName,int iTimeout) 
{ 
	if(WaitNamedPipe(pszPipeName,iTimeout*1000)) 
	{ 
		//create a no share,read/write	 
		HANDLE hP=CreateFile(pszPipeName,GENERIC_WRITE|GENERIC_READ, 
								0,NULL, 
								CREATE_NEW,0, 
								NULL); 
		return hP; 
	} 
	return INVALID_HANDLE_VALUE; 
} 
 
CIPCNamedPipe::CIPCNamedPipe(HANDLE hPipe,BOOL fAutoDel) 
{ 
	ASSERT(hPipe !=NULL); 
	m_fAutoDel=fAutoDel; 
	m_hPipe = hPipe; 
} 
 
CIPCNamedPipe::~CIPCNamedPipe() 
{ 
	if(m_fAutoDel) 
	{ 
		CloseHandle(m_hPipe); 
	} 
} 
 
 
int CIPCNamedPipe::Recv(const int iWant,BYTE* pbBuf,int& iRead) 
{ 
	iRead=0; 
	while(1) 
	{ 
		DWORD dwRead; 
		BOOL fRet = ReadFile(m_hPipe,pbBuf,iWant-iRead,&dwRead,NULL); 
		if(fRet) 
		{ 
			iRead += dwRead; 
			if(iRead == iWant) 
				return SP_ERR_SUCCESS; 
		} 
		else 
			return SP_ERR_NETWORK; 
	} 
} 
 
int CIPCNamedPipe::Send(const int iWant,const BYTE *pbBuf,int& iWrote) 
{ 
	iWrote=0; 
	while(1) 
	{ 
		DWORD dwWrote; 
		BOOL fRet = WriteFile(m_hPipe,pbBuf,iWant - iWrote,&dwWrote,NULL); 
		if(fRet) 
		{ 
			iWrote += dwWrote; 
			if(iWrote ==iWant) 
				return SP_ERR_SUCCESS; 
		} 
		else 
			return SP_ERR_NETWORK; 
	} 
} 
 
int CIPCNamedPipe::TestRead(int iTimeOut) 
{ 
	//return SP_ERR_NOT_IMPLEMENT; 
	DWORD dwRead,dwTotal,dwLeft; 
	DWORD dwT1=GetTickCount(); 
 
	while(1) 
	{ 
		BOOL fRet = PeekNamedPipe(m_hPipe,NULL,0, 
									&dwRead,&dwTotal,&dwLeft); 
		if (!fRet) 
			return SP_ERR_NETWORK; 
		if(dwTotal) 
			return SP_ERR_SUCCESS; 
		DWORD dwT2 = GetTickCount(); 
		if(dwT2-dwT1 > (DWORD)iTimeOut*1000) 
			return SP_ERR_NODATA; 
		Sleep(500); 
	} 
	return SP_ERR_NODATA; 
} 
int CIPCNamedPipe::TestConnect(int iTimeOut) 
{ 
	return SP_ERR_NOT_IMPLEMENT; 
} 
 
int CIPCNamedPipe::RecvWithTimeOut(int iTimeout,const int iWant,BYTE* pbBuf,int& iRead) 
{ 
	iRead =0; 
	DWORD dwTick1 = GetTickCount(); 
	int iRecved=0,iLeft = iWant; 
	iRead = 0; 
	while(1) 
	{ 
		int iTest = TestRead(1); 
		if(SP_ERR_SUCCESS == iTest) 
		{ 
			DWORD dwRead,dwTotal,dwLeftQueue; 
			BOOL fRet = PeekNamedPipe(m_hPipe,NULL,0, 
										&dwRead,&dwTotal,&dwLeftQueue); 
			DWORD dwWantRead = (dwTotal>(DWORD)iLeft)?iLeft:dwTotal; 
			fRet = ReadFile(m_hPipe,pbBuf,dwWantRead,&dwRead,NULL); 
			if(fRet == FALSE) 
				return SP_ERR_NETWORK; 
			iRecved += dwRead; 
			iRead = iRecved; 
			iLeft = iWant - iRecved; 
		} 
		else if(iTest != SP_ERR_NODATA) 
			return iTest; 
 
		if(iRead == iWant) 
			return  SP_ERR_SUCCESS; 
 
		DWORD dwTick2= GetTickCount(); 
		if(dwTick2-dwTick1 > (DWORD)iTimeout*1000) 
		{//检查是否超时 
			if (iRead ==0) 
				return SP_ERR_NODATA; 
			else 
				return SP_ERR_NOT_FINISH; 
		} 
	} 
	return SP_ERR_GENERAL; 
} 
 
int CIPCNamedPipe::TestAndRecv(int iTimeout,const int iWant,BYTE* pbBuf,int& iRead) 
{ 
	iRead =0; 
	int iTest = TestRead(iTimeout); 
	if (iTest != SP_ERR_SUCCESS) 
		return iTest; 
	else 
	{ 
		DWORD dwRead,dwTotal,dwLeftQueue; 
		BOOL fRet = PeekNamedPipe(m_hPipe,NULL,0, 
									&dwRead,&dwTotal,&dwLeftQueue); 
		DWORD dwWantRead = (dwTotal>(DWORD)iWant)?iWant:dwTotal; 
		fRet = ReadFile(m_hPipe,pbBuf,dwWantRead,&dwRead,NULL); 
		iRead= dwRead; 
		if(fRet) 
		{ 
			if(dwRead ==0) 
				return SP_ERR_NODATA; 
			else if( dwRead == (DWORD)iWant) 
				return SP_ERR_SUCCESS; 
			else 
				return SP_ERR_NOT_FINISH; 
		} 
		else 
			return SP_ERR_NETWORK; 
	} 
	return SP_ERR_GENERAL; 
}