📄 csock.cpp
字号:
// 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 + -