📄 csock.cpp
字号:
nWsaError = GetWSALastError();
// legge gli eventuali dati rimanenti
while(remain!=0 && remain!=SOCKET_ERROR)
{
// se non viene passato nessun buffer, scarta i dati pendenti
if(lpszDiscard)
{
remain = CWinsock::recv(m_Socket.socket,&lpszDiscard[offset],nSize,0);
if(remain!=0 && remain!=SOCKET_ERROR)
{
nSize -= remain;
offset += remain;
}
}
else
{
remain = SOCKET_ERROR;
}
}
// resetta il codice d'errore
SetWSALastError(0);
// chiude il socket
if(CWinsock::closesocket(m_Socket.socket)==SOCKET_ERROR)
nWsaError = GetWSALastError();
return(nWsaError);
}
/*
GetIPAddress()
Ricava l'ip relativo al socket.
*/
LPCSTR CSock::GetIPAddress(SOCKET socket/*=INVALID_SOCKET*/)
{
unsigned char* ip;
static char ip_addr[IP_ADDRESS_SIZE+1];
SOCKADDR_IN sockaddr_in;
int sockaddr_size = sizeof(SOCKADDR_IN);
strcpyn(ip_addr,NULL_HOST,sizeof(ip_addr));
// controlla che il costruttore abbia terminato correttamente
if(IsValid())
{
// ricava l'ip del socket
if(socket==INVALID_SOCKET)
socket = m_Socket.socket;
if(CWinsock::getsockname(socket,(SOCKADDR*)&sockaddr_in,&sockaddr_size)==0)
{
ip = (unsigned char*)&(sockaddr_in.sin_addr);
_snprintf(ip_addr,sizeof(ip_addr)-1,"%i.%i.%i.%i",ip[0],ip[1],ip[2],ip[3]);
}
else
GetWSALastError();
}
else
SetWSALastError(WSANOTINITIALISED);
return(ip_addr);
}
/*
CreateListenSocket()
Crea il socket da mettere in ascolto per le connessioni.
Notare che la funzione crea un socket di tipo PF_INET(arpa)/SOCK_STREAM(tcp)/protocollo di default.
*/
#if defined(_WINDOWS)
SOCKET CSock::CreateListenSocket(HWND hWnd,UINT uMsg,UINT nPort)
{
int nWsaError = WSANOTINITIALISED;
SOCKADDR_IN sockaddr_in;
int sockaddr_size = sizeof(SOCKADDR_IN);
// controlla che il costruttore abbia terminato correttamente
if(IsValid())
{
// controlla che il socket non sia gia' aperto
if(m_Socket.socket==INVALID_SOCKET && m_Socket.status==UNDEFINED)
{
if(Create()!=INVALID_SOCKET)
{
// arpa/tcp/protocollo di default
m_Socket.format = PF_INET;
m_Socket.type = SOCK_STREAM;
m_Socket.proto = 0;
m_Socket.status = OPEN;
// famiglia=ARPA, porta=[input], indirizzo=qualunque (INADDR_ANY, per cui bind() utilizza l'indirizzo TCP/IP del computer)
sockaddr_in.sin_family = PF_INET;
sockaddr_in.sin_port = (u_short)CWinsock::htons((u_short)nPort);
sockaddr_in.sin_addr.S_un.S_addr = INADDR_ANY;
// configura il socket per la modalita' asincrona e registra gli eventi da monitorare
if(CWinsock::WSAAsyncSelect(m_Socket.socket,hWnd,uMsg,FD_CONNECT|FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE)==0)
{
// da' il nome al socket
if(CWinsock::bind(m_Socket.socket,(SOCKADDR *)&sockaddr_in,sockaddr_size)==0)
{
// mette il socket in ascolto
if(CWinsock::listen(m_Socket.socket,5)==0)
nWsaError = 0;
}
}
if(nWsaError!=0)
GetWSALastError();
}
}
}
else
SetWSALastError(WSANOTINITIALISED);
return(nWsaError==0 ? INVALID_SOCKET : m_Socket.socket);
}
#endif
/*
AcceptConnectingSocket()
Accetta la connessione sul socket.
*/
#if defined(_WINDOWS)
CSock* CSock::AcceptConnectingSocket(HWND hWnd,UINT uMsg)
{
SOCKET socket;
SOCKADDR_IN sockaddr_in;
int sockaddr_size = sizeof(SOCKADDR_IN);
CSock* pSocket = NULL;
// controlla che il costruttore abbia terminato correttamente
if(IsValid())
{
// accetta la connessione sul socket in ascolto
if((socket = CWinsock::accept(m_Socket.socket,(SOCKADDR*)&sockaddr_in,&sockaddr_size))!=INVALID_SOCKET)
{
// imposta gli eventi da monitorare
CWinsock::WSAAsyncSelect(socket,hWnd,uMsg,FD_CONNECT|FD_ACCEPT|FD_READ|FD_WRITE|FD_CLOSE);
pSocket = new CSock();
if(pSocket)
pSocket->Init(socket,OPEN);
}
else
GetWSALastError();
}
else
SetWSALastError(WSANOTINITIALISED);
return(pSocket);
}
#endif
/*
Send()
Invia i dati presenti nel buffer di output.
*/
int CSock::Send(int nLen/*=-1*/)
{
int nSent = SOCKET_ERROR;
// controlla che il costruttore abbia terminato correttamente
if(IsValid())
{
// calcola la dimensione del buffer
// (se non viene passato il numero di bytes da inviare, il buffer deve essere terminato con \0)
nLen = (nLen <= 0 ? strlen(m_szSendBuffer) : nLen);
if(nLen > 0 && nLen <= WSA_BUF_SIZE)
{
// invia i dati
if((nSent = CWinsock::send(m_Socket.socket,(const char FAR *)m_szSendBuffer,nLen,0))==SOCKET_ERROR)
GetWSALastError();
}
else
SetWSALastError(WSAENOBUFS);
}
else
SetWSALastError(WSANOTINITIALISED);
return(nSent);
}
/*
Send()
Invia i dati.
*/
int CSock::Send(LPCSTR pData,int nLen)
{
int nSent = SOCKET_ERROR;
// controlla che il costruttore abbia terminato correttamente
if(IsValid())
{
// invia i dati
if((nSent = CWinsock::send(m_Socket.socket,(const char FAR *)pData,nLen,0))==SOCKET_ERROR)
GetWSALastError();
}
else
SetWSALastError(WSANOTINITIALISED);
return(nSent);
}
/*
Receive()
Riceve i dati.
*/
const char* CSock::Receive(int* nRecv/*=NULL*/,int nLen/*=-1*/)
{
int nReceived = SOCKET_ERROR;
int nWsaError = WSANOTINITIALISED;
// controlla che il costruttore abbia terminato correttamente
if(IsValid())
{
// calcola il numero di bytes da ricevere
// (se non viene passato il numero di bytes da ricevere, assume WSA_BUF_SIZE)
nLen = (nLen <= 0 ? WSA_BUF_SIZE : nLen);
if(nLen > 0 && nLen <= WSA_BUF_SIZE)
{
// riceve i dati
if((nReceived = CWinsock::recv(m_Socket.socket,(char FAR *)m_szRecvBuffer,nLen,0))!=SOCKET_ERROR)
{
nWsaError = 0;
m_szRecvBuffer[nReceived] = '\0';
}
else
nWsaError = GetWSALastError();
}
else
nWsaError = WSAENOBUFS;
}
else
nWsaError = WSANOTINITIALISED;
if(nWsaError!=0)
SetWSALastError(nWsaError);
if(nRecv)
*nRecv = nReceived;
return(nReceived!=SOCKET_ERROR ? m_szRecvBuffer : NULL);
}
/*
Receive()
Riceve i dati nel buffer di input.
*/
int CSock::Receive(LPSTR pBuffer,int nLen)
{
int nReceived = SOCKET_ERROR;
// controlla che il costruttore abbia terminato correttamente
if(IsValid())
{
// riceve i dati
if((nReceived = CWinsock::recv(m_Socket.socket,(char FAR *)pBuffer,nLen,0))==SOCKET_ERROR)
GetWSALastError();
else
pBuffer[nReceived] = '\0';
}
else
SetWSALastError(WSANOTINITIALISED);
return(nReceived);
}
/*
GetLocalHostName()
Restituisce il nome dell'host locale.
*/
LPCSTR CSock::GetLocalHostName(void)
{
// controlla che il costruttore abbia terminato correttamente
if(!IsValid())
{
SetWSALastError(WSANOTINITIALISED);
return(NULL);
}
else
return(m_szLocalHostName);
}
/*
GetLocalHostAddr()
Restituisce l'indirizzo ip dell'host locale.
*/
LPCSTR CSock::GetLocalHostAddr(void)
{
// controlla che il costruttore abbia terminato correttamente
if(!IsValid())
{
SetWSALastError(WSANOTINITIALISED);
return(NULL);
}
else
return(m_szLocalHostIP);
}
/*
GetHostLocalName()
Ricava il nome dell'host locale.
*/
LPCSTR CSock::GetHostLocalName(void)
{
char* p = m_szLocalHostName;
// ricava il nome
if(CWinsock::gethostname(m_szLocalHostName,sizeof(m_szLocalHostName))==SOCKET_ERROR)
{
GetWSALastError();
memset(m_szLocalHostName,'\0',sizeof(m_szLocalHostName));
p = NULL;
}
return(p);
}
/*
GetHostLocalAddr()
Ricava l'ip dell'host locale.
*/
LPCSTR CSock::GetHostLocalAddr(void)
{
LPHOSTENT pHostEnt;
SOCKADDR_IN sockaddr_in_local;
SOCKADDR_IN sockaddr_in_remote;
int sockaddr_size = sizeof(SOCKADDR);
char* p = NULL;
// inizializza l'indirizzo locale
strcpy(m_szLocalHostIP,NULL_HOST);
sockaddr_in_local.sin_addr.s_addr = INADDR_ANY;
// ricava il nome
if(CWinsock::gethostname(m_szLocalHostName,sizeof(m_szLocalHostName))!=SOCKET_ERROR)
{
// ricava le informazioni sull'host relative al nome
if((pHostEnt = CWinsock::gethostbyname(m_szLocalHostName))!=(LPHOSTENT)NULL)
{
sockaddr_in_local.sin_addr.s_addr = *((u_long FAR*)(pHostEnt->h_addr));
strncpy(m_szLocalHostIP,CWinsock::inet_ntoa(sockaddr_in_local.sin_addr),HOSTNAME_SIZE);
p = m_szLocalHostIP;
}
}
// errore, prova con un socket fittizzio
if(sockaddr_in_local.sin_addr.s_addr==INADDR_ANY)
{
SOCKET socket;
// prova con un socket UDP
if((socket = CWinsock::socket(AF_INET,SOCK_DGRAM,0))!=INVALID_SOCKET)
{
// collega ad un indirizzo fittizzio (non usare il loopback) */
sockaddr_in_remote.sin_family = AF_INET;
sockaddr_in_remote.sin_port = CWinsock::htons(IPPORT_ECHO);
sockaddr_in_remote.sin_addr.s_addr = CWinsock::inet_addr(DUMMY_HOST);
if(CWinsock::connect(socket,(LPSOCKADDR)&sockaddr_in_remote,sizeof(SOCKADDR))!=SOCKET_ERROR)
{
// ricava l'indirizzo locale
if(CWinsock::getsockname(socket,(LPSOCKADDR)&sockaddr_in_local,(int FAR*)&sockaddr_size)!=SOCKET_ERROR)
{
strncpy(m_szLocalHostIP,CWinsock::inet_ntoa(sockaddr_in_local.sin_addr),HOSTNAME_SIZE);
p = m_szLocalHostIP;
}
}
CWinsock::closesocket(socket);
}
}
return(p);
}
/*
GetHostByName()
Ricava l'ip dell'host a partire del nome.
*/
LPCSTR CSock::GetHostByName(LPCSTR lpcszHost)
{
LPHOSTENT pHostEnt;
char* pHostAddr = NULL;
if((pHostEnt = GetHostInfo(lpcszHost))!=(LPHOSTENT)NULL)
{
struct in_addr st_addr;
st_addr.s_addr = *((u_long FAR*)(pHostEnt->h_addr));
pHostAddr = CWinsock::inet_ntoa(st_addr);
}
return(pHostAddr);
}
/*
GetHostByAddr()
Ricava il nome dell' host partire dell'indirizzo ip.
*/
const char* CSock::GetHostByAddr(const char* lpcszHostAddr)
{
LPHOSTENT pHostEnt;
char* pHostName = NULL;
if((pHostEnt = GetHostInfo(lpcszHostAddr))!=(LPHOSTENT)NULL)
pHostName = pHostEnt->h_name;
return(pHostName);
}
/*
GetHostInfo()
Ricava le informazioni relative all'host specificato, distinguendo se si sta' referenziando
l'host locale (ad es. MiPC.medusa.es o 127.0.0.1) o meno.
Notare che considera come host locale il nome del computer (MiPC.medusa.es) o quanto indicato
dalla macro LOCAL_HOST (vedi lmhosts.h).
L' host puo' essere specificato nei due formati: stringa (MiPC.medusa.es) o n.n.n.n (127.0.0.1).
Il formato utilizzato per il socket e' PF_INET.
*/
LPHOSTENT CSock::GetHostInfo(LPCSTR lpcszHost)
{
// valori per la struct HOSTENT statica
static char* host_alias[] = {NULL,NULL};
static struct in_addr st_addr;
st_addr.S_un.S_addr = LOCAL_HOST_NUM;
static char* host_names[] = {(char FAR *)&st_addr,NULL};
static HOSTENT host_ent = {0};
LPHOSTENT pHostEnt = (LPHOSTENT)NULL;
// controlla che il costruttore abbia terminato correttamente
if(!IsValid())
{
SetWSALastError(WSANOTINITIALISED);
return((LPHOSTENT)NULL);
}
// se viene referenziato l'host locale collega sulla struttura interna
if(strcmp(lpcszHost,m_szLocalHostName)==0 || strcmp(lpcszHost,host_names[0])==0 || strcmp(lpcszHost,LOCAL_HOST)==0)
{
host_ent.h_name = m_szLocalHostName;
host_ent.h_aliases = host_alias;
host_ent.h_addrtype = PF_INET;
host_ent.h_length = 4;
host_ent.h_addr_list = host_names;
pHostEnt = &host_ent;
}
else
{
unsigned long lAddr;
/* "n.n.n.n" -> long */
if((lAddr=CWinsock::inet_addr(lpcszHost))!=INADDR_NONE)
pHostEnt = CWinsock::gethostbyaddr((const char FAR *)&lAddr,4,PF_INET); // n.n.n.n (long)
else
pHostEnt = CWinsock::gethostbyname((const char FAR *)lpcszHost); // "host.domain"
}
if(pHostEnt==(LPHOSTENT)NULL)
GetWSALastError();
return(pHostEnt);
}
/*
GetServiceByName()
Ricava il # della porta corrispondente al servizio.
Prima di chiamare winsock controlla nel database (locale).
*/
int CSock::GetServiceByName(LPCSTR lpcszService,LPCSTR lpcszProto/*="tcp"*/,BOOL bUseLocalDabatase/*=TRUE*/)
{
struct servent *se;
int port = -1;
// 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(stricmp(lpcszService,s->service)==0)
if(stricmp(lpcszProto,s->proto)==0)
{
port = s->port;
break;
}
iter = m_pServicesList.Next(iter);
}
}
// se non trova il servizio chiama winsock
if(port < 0)
if((se = CWinsock::getservbyname(lpcszService,lpcszProto))!=(struct servent *)NULL)
port = (int)se->s_port;
return(port);
}
/*
GetServiceByPort()
Ricava il nome del servizio corrispondente al # porta.
Prima di chiamare winsock controlla nel database (locale).
*/
LPCSTR CSock::GetServiceByPort(UINT port,LPCSTR lpcszProto/*="tcp"*/,BOOL bUseLocalDabatase/*=TRUE*/)
{
struct servent *se;
char* p;
static char name[SERVICE_NAME + 1];
p = NULL;
memset(name,'\0',sizeof(name));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -