⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 csock.cpp

📁 <Visual C++ 网络程序设计实例详解>配套源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:

	// cerca il servizio nell'array
	if(bUseLocalDabatase)
	{
		if(m_pServicesList.Count() <= 0)
			LoadServices();

		ITERATOR iter;
		SERVICES* s;
		if((iter = m_pServicesList.First())!=(ITERATOR)NULL)
			while(iter!=(ITERATOR)NULL)
			{
				s = (SERVICES*)iter->data;
				
				if(port==s->port)
					if(stricmp(lpcszProto,s->proto)==0)
					{
						strncpy(name,s->service,SERVICE_NAME+1);
						p = name;
						break;
					}

				iter = m_pServicesList.Next(iter);
			}
	}

	// se non trova il servizio chiama winsock
	if(!p)
	{
		if((se=CWinsock::getservbyport(port,lpcszProto))!=(struct servent *)NULL)
		{
			strncpy(name,se->s_name,SERVICE_NAME);
			p = name;
		}
		else
			p = "unknow";
	}

	return(p);
}

/*
	LoadServices()

	Carica la lista con i servizi presenti nel database.
	Il formato del database e' il seguente:
	<service> <port>/<protocol> [aliases...] [#comment]
	Il carattere #, all'interno del file, viene usato come commento.
*/
int CSock::LoadServices(LPCSTR filename/*=NULL*/)
{
	int i;
	int read = 0;
	CTextFile services_file;
	char *token;
	char buffer[SERVICE_NAME+PORT_NAME+PROTOCOL_NAME+COMMENT_NAME+1];
	char service[SERVICE_NAME+1];
	char port_number[PORT_NAME+1];
	char protocol[PROTOCOL_NAME+1];
	char comment[COMMENT_NAME+1];
	char database[(_MAX_PATH*2)+1];
	SERVICES* s;
	ITERATOR iter;

	if(!filename)
	{
#if defined(_WINDOWS)
		DWORD dwVersion = ::GetVersion();
		DWORD dwWindowsMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
		char szWindowsDir[_MAX_PATH+1];
		::GetWindowsDirectory(szWindowsDir,sizeof(szWindowsDir)-1);

		// Windows NT
		if(dwVersion < 0x80000000)
			_snprintf(database,sizeof(database)-1,"%s\\system32\\drivers\\etc\\services",szWindowsDir);
		// Win32s
		else if(dwWindowsMajorVersion < 4)
			strcpy(database,"services");
		// Windows 95
		else
			_snprintf(database,sizeof(database)-1,"%s\\services",szWindowsDir);
#else
		return(-1);
#endif
	}
	else
	{
		strcpyn(database,filename,sizeof(database));
	}
 
	// apre il file dei servizi caricandolo nell'array
 	if(services_file.Open(database))
	{
		while((read = services_file.ReadLine(buffer,sizeof(buffer)-1))!=FILE_EOF)
		{
			// salta i commenti e le linee vuote
			if(buffer[0]=='#' || isspace(buffer[0]) || buffer[0]=='\r' || read==0)
				continue;

			memset(service,'\0',sizeof(service));
			memset(port_number,'\0',sizeof(port_number));
			memset(protocol,'\0',sizeof(protocol));
			memset(comment,'\0',sizeof(comment));

			if((token = strchr(buffer,'#'))!=NULL)
			{
				token++;

				while(*token && isspace(*token))
					token++;

				for(i = 0; i < sizeof(comment) && *token && !isspace(*token); i++)
					comment[i] = *token++;
			}

			for(i = 0,token = strtok(buffer," \t/"); token!=NULL; i++)
			{
				switch(i)
				{
					case 0:
						strcpyn(service,token,sizeof(service));
						break;
					case 1:
						strcpyn(port_number,token,sizeof(port_number));
						break;
					case 2:
						strcpyn(protocol,token,sizeof(protocol));
						break;
					default:
						break;
				}

				token = strtok(NULL," \t/");
			}
			
			BOOL found = FALSE;

			// controlla che il servizio non esista gia'
			if((iter = m_pServicesList.First())!=(ITERATOR)NULL)
				while(iter!=(ITERATOR)NULL)
				{
					s = (SERVICES*)iter->data;
					if(strcmp(s->service,service)==0)
					{
						found = TRUE;
						break;
					}

					iter = m_pServicesList.Next(iter);
				}
			
			// carica il servizio
			if(!found)
			{
				s = new SERVICES(service,atoi(port_number),protocol,comment[0]!='\0' ? comment : " ");
				if(s)
					m_pServicesList.Add(s);
			}
		}

		services_file.Close();
	}

	return(m_pServicesList.Count());
}

/*
	ParseIPRange()

	Restituisce gli indirizzi ip compresi nell'intervallo.
*/
LPCSTR CSock::ParseIPRange(LPCSTR start_addr,LPCSTR end_addr)
{
	char* pHostAddr = NULL;
	static BOOL first_call = TRUE;
	static IP_RANGE ip_range = {0};

	if(first_call)
	{
		unsigned int a,b,c,d;
		char ip_start_addr[IP_ADDRESS_SIZE+1],ip_end_addr[IP_ADDRESS_SIZE+1];

		if(ValidateIPAddr(start_addr))
			strncpy(ip_start_addr,start_addr,IP_ADDRESS_SIZE);
		else
		{
			if((pHostAddr = (char*)GetHostByName(start_addr))!=NULL)
				strncpy(ip_start_addr,pHostAddr,IP_ADDRESS_SIZE);
			else
				goto done;
		}

		if(ValidateIPAddr(end_addr))
			strncpy(ip_end_addr,end_addr,IP_ADDRESS_SIZE);
		else
		{
			if((pHostAddr = (char*)GetHostByName(end_addr))!=NULL)
				strncpy(ip_end_addr,pHostAddr,IP_ADDRESS_SIZE);
			else
				goto done;
		}
		
		strcpy(ip_range.ip_start,ip_start_addr);
		strcpy(ip_range.ip_end,ip_end_addr);
		
		TokenizeIPAddr(ip_start_addr,a,b,c,d);
		ip_range.a_start = a;
		ip_range.b_start = b;
		ip_range.c_start = c;
		ip_range.d_start = d;
		
		TokenizeIPAddr(ip_end_addr,a,b,c,d);
		ip_range.a_end = a;
		ip_range.b_end = b;
		ip_range.c_end = c;
		ip_range.d_end = d;

		first_call = FALSE;
	}

	pHostAddr = (char*)GetIPFromRange(&ip_range);

	if(!pHostAddr)
	{
		first_call = TRUE;
		memset(&ip_range,'\0',sizeof(IP_RANGE));
	}

done:

	return(pHostAddr);
}

/*
	ValidateIPAddr()

	Controlla la validita' (formale) dell'indirizzo ip.
*/
BOOL CSock::ValidateIPAddr(const char* ip_address)
{
	char* token;
	char* ip;
	int ip_number,ip_len;
	char ip_addr[IP_ADDRESS_SIZE + 1];
	int i = -1;

	strncpy(ip_addr,ip_address,IP_ADDRESS_SIZE);
		
	for(token = strtok(ip_addr,"."); token!=NULL; token = strtok(NULL,"."))
	{
		ip = token;
		ip_len = strlen(ip);

		for(i = 0; i < ip_len; i++)
		{
			if(!isdigit(ip[i]))
			{
				i = -1;
				break;
			}
		}

		if(i < 0)
			break;
		
		ip_number = atoi(ip);

		if(ip_number < 0 || ip_number > 255)
		{
			i = -1;
			break;
		}
	}

	return(i >= 0);
}

/*
	TokenizeIPAddr()

	Scompone l'indirizzo ip ("127.0.0.1") ricavando i valori numerici relativi (a=127, b=0, c=0, d=1).
*/
void CSock::TokenizeIPAddr(const char* ip_address,unsigned int& a,unsigned int& b,unsigned int& c,unsigned int& d)
{
	int i;
	char* token;
	char ip_addr[IP_ADDRESS_SIZE + 1];

	strncpy(ip_addr,ip_address,IP_ADDRESS_SIZE);

	token = strtok(ip_addr,".");
	
	for(i = 0; token!=NULL; i++)
	{
		switch(i)
		{
			case 0:
				a = atoi(token);
				break;
			case 1:
				b = atoi(token);
				break;
			case 2:
				c = atoi(token);
				break;
			case 3:
				d = atoi(token);
				break;
		}
		
		token = strtok(NULL,".");
	}
}

/*
	GetIPFromRange()

	Restituisce l'indirizzo ip successivo (relativamente all'intervallo specificato).
*/
const char* CSock::GetIPFromRange(IP_RANGE *ip)
{
	#define CHECK_IP(f,a,b,c,d) {if(a==b) f = (c < d); else f = (c < (int)256);}
	#define CHECK_CLASS(a) {if(a > (int)255) a = 0;}
	
	BOOL next_class = FALSE;
	static char ip_addr[IP_ADDRESS_SIZE + 1];
	static BOOL first_call = TRUE;

	if(first_call)
	{
		first_call = FALSE;

		CHECK_CLASS(ip->a_start);
		CHECK_CLASS(ip->b_start);
		CHECK_CLASS(ip->c_start);
		CHECK_CLASS(ip->d_start);
		
		_snprintf(ip_addr,sizeof(ip_addr)-1,"%d.%d.%d.%d",ip->a_start,ip->b_start,ip->c_start,ip->d_start);
		
		return(ip_addr);
	}

d_1:

	CHECK_IP(next_class,ip->c_start,ip->c_end,ip->d_start,ip->d_end);

	if(next_class)
	{
		ip->d_start++;

		CHECK_CLASS(ip->a_start);
		CHECK_CLASS(ip->b_start);
		CHECK_CLASS(ip->c_start);
		CHECK_CLASS(ip->d_start);
		
		_snprintf(ip_addr,sizeof(ip_addr)-1,"%d.%d.%d.%d",ip->a_start,ip->b_start,ip->c_start,ip->d_start);
		
		return(ip_addr);
	}

// c_1:

	CHECK_IP(next_class,ip->b_start,ip->b_end,ip->c_start,ip->c_end);

	if(next_class)
	{
		ip->d_start = -1;
		ip->c_start++;
		goto d_1;
	}

// b_1:

	CHECK_IP(next_class,ip->a_start,ip->a_end,ip->b_start,ip->b_end);

	if(next_class)
	{
		ip->d_start = -1;
		ip->c_start = 0;
		ip->b_start++;
		goto d_1;
	}

// a_1:

	if(ip->a_start < ip->a_end)
	{
		ip->d_start = -1;
		ip->c_start = 0;
		ip->b_start = 0;
		ip->a_start++;
		goto d_1;
	}

	first_call = TRUE;

	return(NULL);
}

/*
	IsWSAError()

	Controlla se il codice fa riferimento ad un errore.
*/
BOOL CSock::IsWSAError(int iWSAError)
{
	BOOL bFlag = FALSE;
	register int i;

	// cerca il codice d'errore nell'array
	for(i = 0; i < WSAERRORCODE_ARRAY_SIZE ;i++)
		if(wsa_errorcode_num[i]==iWSAError)
		{
			bFlag = TRUE;
			break;
		}

	return(bFlag);
}

/*
	ShowErrors()

	Imposta il flag per la visualizzazione degli errori.
*/
#if defined(_WINDOWS)
void CSock::ShowErrors(BOOL bFlag)
{
	// controlla che il costruttore abbia terminato correttamente
	if(IsValid())
		m_bShowErrors = bFlag;
	else
		SetWSALastError(WSANOTINITIALISED);
}
#endif

/*
	GetWSAErrorNumber()

	Restituisce l'ultimo codice d'errore numerico WSA.
*/
const int CSock::GetWSAErrorNumber(void)
{
	return(m_WsaData.error);
}

/*
	GetWSAErrorString()

	Restituisce la descrizione relativa all'ultimo codice d'errore WSA.
*/
const char* CSock::GetWSAErrorString(void)
{
	return(m_WsaData.errorstr);
}

/*
	GetWSALastError()

	Ricava l'ultimo errore winsock, impostando di conseguenza i campi relativi della struttura
	del socket e dei dati wsa.
*/
int CSock::GetWSALastError(int iWSAError)
{
	register int i;

	// ricava il codice d'errore
	if(iWSAError==WSA_GETLASTERROR)
	{
		if((iWSAError = CWinsock::WSAGetLastError())==0)
			iWSAError = WSA_SUCCESS;
	}

	if(iWSAError!=WSA_SUCCESS)
	{
		// imposta il codice d'errore (numerico)
		m_Socket.error = m_WsaData.error = iWSAError;

		/* cerca il codice d'errore nell'array */
		for(i=0; i < WSAERRORCODE_ARRAY_SIZE ;i++)
			if(wsa_errorcode_num[i]==m_WsaData.error)
				break;

		// ricava il codice d'errore (stringa)
		_snprintf(m_WsaData.errorstr,sizeof(m_WsaData.errorstr)-1,"%s (%d)",wsa_errorcode_str[(i >= WSAERRORCODE_ARRAY_SIZE ? WSAERRORCODE_ARRAY_SIZE-1 : i)],m_WsaData.error);

#if defined(_WINDOWS)
		// visualizza l'errore
		if(m_bShowErrors)
#ifdef WIN32_MFC
			::MessageBox(m_pParent ? m_pParent->m_hWnd : NULL,m_WsaData.errorstr,"CSock::GetWSALastError()",MB_ICONERROR|MB_SETFOREGROUND|MB_TOPMOST);
#else
			::MessageBox(m_hWnd,m_WsaData.errorstr,"CSock::GetWSALastError()",MB_ICONERROR|MB_SETFOREGROUND|MB_TOPMOST);
#endif
#endif
	}
	else
	{
		m_Socket.error = m_WsaData.error = iWSAError = 0;
		strcpy(m_WsaData.errorstr,"");
	}

	return(iWSAError);
}

/*
	SetWSALastError()

	Imposta il codice d'errore winsock, impostando di conseguenza i campi relativi della struttura
	del socket e dei dati wsa.
*/
int CSock::SetWSALastError(int iWSAError)
{
	// imposta il codice d'errore (numerico)
	m_Socket.error = m_WsaData.error = iWSAError;

	if(iWSAError > 0)
	{
		register int i;

		// cerca il codice d'errore nell'array
		for(i = 0; i < WSAERRORCODE_ARRAY_SIZE ;i++)
			if(wsa_errorcode_num[i]==m_WsaData.error)
				break;

		// imposta il codice d'errore (stringa)
		_snprintf(m_WsaData.errorstr,sizeof(m_WsaData.errorstr)-1,"%s (%d)",wsa_errorcode_str[(i >= WSAERRORCODE_ARRAY_SIZE ? WSAERRORCODE_ARRAY_SIZE-1 : i)],m_WsaData.error);
	}
	else
		strcpy(m_WsaData.errorstr,"");
	
	CWinsock::WSASetLastError(iWSAError);

	return(iWSAError);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -