📄 casyncsock.cpp
字号:
m_pAsyncSock->SetWSALastError(wWSAError);
static char szWSAString[128];
strcpyn(szWSAString,m_pAsyncSock->GetWSAErrorString(),sizeof(szWSAString));
switch(wWSAEvent)
{
case FD_READ:
if(m_pAsyncSock)
m_pAsyncSock->AsyncReadCallBack(wWSAError,MAKELPARAM(LOWORD(szWSAString),HIWORD(szWSAString)));
break;
case FD_WRITE:
if(m_pAsyncSock)
m_pAsyncSock->AsyncWriteCallBack(wWSAError,MAKELPARAM(LOWORD(szWSAString),HIWORD(szWSAString)));
break;
case FD_OOB:
break;
case FD_ACCEPT:
break;
case FD_CONNECT:
if(m_pAsyncSock)
m_pAsyncSock->AsyncConnectCallBack(wWSAError,MAKELPARAM(LOWORD(szWSAString),HIWORD(szWSAString)));
break;
case FD_CLOSE:
if(m_pAsyncSock)
m_pAsyncSock->AsyncCloseCallBack(wWSAError,MAKELPARAM(LOWORD(szWSAString),HIWORD(szWSAString)));
break;
}
return(0L);
}
/*
CAsyncSock()
*/
CAsyncSock::CAsyncSock(CWnd* pParent) : CSock(pParent)
{
CSock::m_bInitialized = FALSE;
// azzera i buffer interni
memset(m_szAsyncGetHostByName,'\0',sizeof(m_szAsyncGetHostByName));
memset(m_szAsyncGetHostByAddr,'\0',sizeof(m_szAsyncGetHostByAddr));
memset(m_szAsyncGetServByName,'\0',sizeof(m_szAsyncGetServByName));
memset(m_szAsyncGetServByPort,'\0',sizeof(m_szAsyncGetServByPort));
// crea la finestra interna
m_pSockWnd = new CSockWnd(this,pParent);
if(m_pSockWnd)
{
m_pSockWnd->ShowWindow(SW_HIDE);
m_pSockWnd->UpdateWindow();
}
else
return;
CSock::m_bInitialized = TRUE;
CSock::ShowErrors(FALSE);
}
/*
~CAsyncSock()
*/
CAsyncSock::~CAsyncSock(void)
{
// chiude il socket
CSock::Close();
// elimina la finestra interna
if(m_pSockWnd)
delete m_pSockWnd,m_pSockWnd = NULL;
}
/*
Create()
Ridefinisce la virtual di CSock per la gestione degli eventi asincroni.
Gi eventi (FD_READ, etc.) vengono direzionati alla finestra di CSockWnd che chiama la
callback di CAsyncSock corrispondente.
*/
SOCKET CAsyncSock::Create(void)
{
SOCKET s = INVALID_SOCKET;
int nWSAError = SOCKET_ERROR;
// controlla che il costruttore abbia terminato correttamente
if(CSock::m_bInitialized)
{
// crea il socket tramite CSock e imposta l'handler per i messaggi asincroni
if((s = CSock::Create())!=INVALID_SOCKET)
{
// controlla il puntatore alla finestra per i messaggi asincroni
if(m_pSockWnd && m_pSockWnd->m_hWnd)
{
// imposta l'handler
if((nWSAError = ::WSAAsyncSelect(s,m_pSockWnd->m_hWnd,WM_ASYNCSELECT,FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT|FD_CLOSE))==SOCKET_ERROR)
nWSAError = CSock::GetWSALastError(WSA_GETLASTERROR);
}
}
// impostazione gestione asincrona fallita, chiude il socket (con CSock)
if(nWSAError==SOCKET_ERROR && s!=INVALID_SOCKET)
CSock::Close();
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
return(nWSAError==SOCKET_ERROR ? INVALID_SOCKET : s);
}
/*
Close()
Ridefinisce la virtual di CSock per la gestione degli eventi asincroni.
*/
int CAsyncSock::Close(LPSTR /*lpDiscardBuffer*/,int /*iBufferLen*/)
{
// controlla che il costruttore abbia terminato correttamente
if(CSock::m_bInitialized)
{
// controlla il puntatore alla finestra per i messaggi asincroni
if(m_pSockWnd && m_pSockWnd->m_hWnd)
{
// elimina l'handler per la gestione dei messaggi asincroni
if(::WSAAsyncSelect(CSock::GetHandle(),m_pSockWnd->m_hWnd,0,0)==SOCKET_ERROR)
CSock::GetWSALastError(WSA_GETLASTERROR);
}
// chiude il socket (con CSock)
CSock::Close();
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
return(0);
}
/*
AsyncConnect()
Effettua il collegamento all'host/porta.
L'host deve essere specificato attraverso il relativo indirizzo ip in formato stringa.
L'applicazione, al termine dell'operazione, ricevera' il messaggio WM_ASYNSELECT.
input:
LPCSTR ptr all'ip in formato stringa ("n.n.n.n")
UINT numero porta
output:
BOOL flag per collegamento riuscito
*/
BOOL CAsyncSock::AsyncConnect(LPCSTR lpcszIPAddr,UINT m_nPort)
{
BOOL bConnected = FALSE;
int nWSAError = 0;
// controlla che il costruttore abbia terminato correttamente
if(CSock::m_bInitialized)
{
// controlla che sia un indirizzo valido ("n.n.n.n")
if(CSock::ValidateIPAddr(lpcszIPAddr))
{
SOCKADDR_IN sockaddr_in;
// imposta il socket (tipo, porta, indirizzo)
sockaddr_in.sin_family = PF_INET;
sockaddr_in.sin_port = ::htons((u_short)m_nPort);
sockaddr_in.sin_addr.S_un.S_addr = ::inet_addr(lpcszIPAddr);
// collega il socket
if(::connect(CSock::GetHandle(),(SOCKADDR *)&sockaddr_in,SOCKADDR_IN_LEN)==SOCKET_ERROR)
{
// nel caso di socket asincroni connect() genera un WSAEWOULDBLOCK
if((nWSAError=CSock::GetWSALastError(WSA_GETLASTERROR))==WSAEWOULDBLOCK)
bConnected = TRUE;
}
else
bConnected = TRUE;
}
else
nWSAError = CSock::SetWSALastError(WSAEDESTADDRREQ);
}
else
nWSAError = CSock::SetWSALastError(WSANOTINITIALISED);
// connessione fallita, invia autonomamente il messaggio all'applicazione perche' se connect()
// fallisce non viene eseguita la callback
if(!bConnected)
{
if(CSock::m_pParent)
CSock::m_pParent->PostMessage(WM_ASYNCCONNECT,nWSAError,MAKELPARAM(0,nWSAError));
}
return(bConnected);
}
/*
AsyncConnectCallback()
Callback per CSockWnd::OnAsyncSelect().
Invia il messaggio di connessione avvenuta (WM_ASYNCCONNECT) all'applicazione.
*/
LONG CAsyncSock::AsyncConnectCallBack(UINT wParam,LONG lParam)
{
// in wParam l'errore Winsock
if(wParam!=0)
CSock::SetWSALastError(wParam);
// invia il messaggio all'applicazione (controlla che sia stata specificata una finestra)
if(CSock::m_pParent)
CSock::m_pParent->PostMessage(WM_ASYNCCONNECT,wParam,lParam);
return(0L);
}
/*
AsyncWriteCallback()
Callback per CSockWnd::OnAsyncSelect().
Invia il messaggio socket pronto in scrittura (WM_ASYNCWRITE) all'applicazione.
*/
LONG CAsyncSock::AsyncWriteCallBack(UINT wParam,LONG lParam)
{
// in wParam l'errore Winsock
if(wParam!=0)
CSock::SetWSALastError(wParam);
// invia il messaggio all'applicazione (controlla che sia stata specificata una finestra)
if(CSock::m_pParent)
CSock::m_pParent->PostMessage(WM_ASYNCWRITE,wParam,lParam);
return(0L);
}
/*
AsyncReadCallback()
Callback per CSockWnd::OnAsyncSelect().
Invia il messaggio socket pronto in lettura (WM_ASYNCREAD) all'applicazione.
*/
LONG CAsyncSock::AsyncReadCallBack(UINT wParam,LONG lParam)
{
// in wParam l'errore Winsock
if(wParam!=0)
CSock::SetWSALastError(wParam);
// invia il messaggio all'applicazione (controlla che sia stata specificata una finestra)
if(CSock::m_pParent)
CSock::m_pParent->PostMessage(WM_ASYNCREAD,wParam,lParam);
return(0L);
}
/*
AsyncCloseCallback()
Callback per CSockWnd::OnAsyncSelect().
Invia il messaggio di chiusura socket (WM_ASYNCCLOSE) all'applicazione.
*/
LONG CAsyncSock::AsyncCloseCallBack(UINT wParam,LONG lParam)
{
// in wParam l'errore Winsock
if(wParam!=0)
CSock::SetWSALastError(wParam);
// invia il messaggio all'applicazione (controlla che sia stata specificata una finestra)
if(CSock::m_pParent)
CSock::m_pParent->PostMessage(WM_ASYNCCLOSE,wParam,lParam);
return(0L);
}
/*
AsyncGetHostByName()
Ricava l'indirizzo ip relativo al nome host in modo asincrono.
L'applicazione, al termine dell'operazione, ricevera' il messaggio WM_ASYNCGETHOSTBYNAME.
input:
LPCSTR ptr al nome host
output:
BOOL flag per operazione riuscita
*/
BOOL CAsyncSock::AsyncGetHostByName(LPCSTR lpcszHostName)
{
BOOL bGet = FALSE;
// controlla che il costruttore abbia terminato correttamente
if(CSock::m_bInitialized)
{
// controlla che esista la finestra interna
if(m_pSockWnd)
{
int nWSAError;
// chiama la async di CSockWnd, l'applicazione ricevera il messaggio tramite le callback
if((nWSAError=m_pSockWnd->AsyncGetHostByName(lpcszHostName,m_szAsyncGetHostByName,sizeof(m_szAsyncGetHostByName)))!=0)
CSock::SetWSALastError(nWSAError);
bGet = (nWSAError==0);
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
return(bGet);
}
/*
AsyncGetHostByNameCallBack()
Callback per CSockWnd::OnAsyncGetHostByName().
Invia il messaggio WM_ASYNCGETHOSTBYNAME all'applicazione.
*/
LONG CAsyncSock::AsyncGetHostByNameCallBack(UINT wParam,LONG lParam)
{
// in wParam l'errore Winsock
if(wParam!=0)
CSock::SetWSALastError(wParam);
CAsyncSock::OnAsyncGetHostByName((LPCSTR)lParam);
// invia il messaggio all'applicazione (controlla che sia stata specificata una finestra)
if(CSock::m_pParent)
CSock::m_pParent->PostMessage(WM_ASYNCGETHOSTBYNAME,wParam,lParam);
return(0L);
}
/*
AsyncGetHostByAddr()
Ricava il nome dell'host relativo all'indirizzo ip in modo asincrono.
L'applicazione, al termine dell'operazione, ricevera' il messaggio WM_ASYNCGETHOSTBYADDR.
input:
LPCSTR ptr all'indirizzo ip
output:
BOOL flag per operazione riuscita
*/
BOOL CAsyncSock::AsyncGetHostByAddr(LPCSTR lpcszHostIP)
{
BOOL bGet = FALSE;
// controlla che il costruttore abbia terminato correttamente
if(CSock::m_bInitialized)
{
// controlla che esista la finestra interna
if(m_pSockWnd)
{
int nWSAError;
// chiama la async di CSockWnd, l'applicazione ricevera il messaggio tramite le callback
if((nWSAError=m_pSockWnd->AsyncGetHostByAddr(lpcszHostIP,m_szAsyncGetHostByAddr,sizeof(m_szAsyncGetHostByAddr)))!=0)
CSock::SetWSALastError(nWSAError);
bGet = (nWSAError==0);
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
return(bGet);
}
/*
AsyncGetHostByAddrCallBack()
Callback per CSockWnd::OnAsyncGetHostByAddr().
Invia il messaggio WM_ASYNCGETHOSTBYADDR all'applicazione.
*/
LONG CAsyncSock::AsyncGetHostByAddrCallBack(UINT wParam,LONG lParam)
{
// in wParam l'errore Winsock
if(wParam!=0)
CSock::SetWSALastError(wParam);
CAsyncSock::OnAsyncGetHostByAddr((LPCSTR)lParam);
// invia il messaggio all'applicazione (controlla che sia stata specificata una finestra)
if(CSock::m_pParent)
CSock::m_pParent->PostMessage(WM_ASYNCGETHOSTBYADDR,wParam,lParam);
return(0L);
}
/*
AsyncGetServByName()
Ricava il # della porta corrispondente al servizio in modo asincrono.
L'applicazione, al termine dell'operazione, ricevera' il messaggio WM_ASYNCGETSERVBYNAME.
input:
LPCSTR ptr al nome del servizio
output:
BOOL flag per operazione riuscita
*/
BOOL CAsyncSock::AsyncGetServByName(LPCSTR lpcszService,LPCSTR lpcszProto)
{
BOOL bGet = FALSE;
// controlla che il costruttore abbia terminato correttamente
if(CSock::m_bInitialized)
{
// controlla che esista la finestra interna
if(m_pSockWnd)
{
int nWSAError;
// chiama la async di CSockWnd, l'applicazione ricevera il messaggio tramite le callback
if((nWSAError=m_pSockWnd->AsyncGetServByName(lpcszService,lpcszProto,m_szAsyncGetServByName,sizeof(m_szAsyncGetServByName)))!=0)
CSock::SetWSALastError(nWSAError);
bGet = (nWSAError==0);
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
return(bGet);
}
/*
AsyncGetServByNameCallBack()
Callback per CSockWnd::OnAsyncGetServByName().
Invia il messaggio WM_ASYNCGETSERVBYNAME all'applicazione.
*/
LONG CAsyncSock::AsyncGetServByNameCallBack(UINT wParam,LONG lParam)
{
// in wParam l'errore Winsock
if(wParam!=0)
CSock::SetWSALastError(wParam);
CAsyncSock::OnAsyncGetServByName((UINT)lParam);
// invia il messaggio all'applicazione (controlla che sia stata specificata una finestra)
if(CSock::m_pParent)
CSock::m_pParent->PostMessage(WM_ASYNCGETSERVBYNAME,wParam,lParam);
return(0L);
}
/*
AsyncGetServByPort()
Ricava il servizio corrispondente al # della porta in modo asincrono.
L'applicazione, al termine dell'operazione, ricevera' il messaggio WM_ASYNCGETSERVBYPORT.
input:
UINT numero porta
output:
BOOL flag per operazione riuscita
*/
BOOL CAsyncSock::AsyncGetServByPort(UINT m_nPort,LPCSTR lpcszProto)
{
BOOL bGet = FALSE;
// controlla che il costruttore abbia terminato correttamente
if(CSock::m_bInitialized)
{
// controlla che esista la finestra interna
if(m_pSockWnd)
{
int nWSAError;
// chiama la async di CSockWnd, l'applicazione ricevera il messaggio tramite le callback
if((nWSAError=m_pSockWnd->AsyncGetServByPort(m_nPort,lpcszProto,m_szAsyncGetServByPort,sizeof(m_szAsyncGetServByPort)))!=0)
CSock::SetWSALastError(nWSAError);
bGet = (nWSAError==0);
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
}
else
CSock::SetWSALastError(WSANOTINITIALISED);
return(bGet);
}
/*
AsyncGetServByPortCallBack()
Callback per CSockWnd::OnAsyncGetServByPort().
Invia il messaggio WM_ASYNCGETSERVBYPORT all'applicazione.
*/
LONG CAsyncSock::AsyncGetServByPortCallBack(UINT wParam,LONG lParam)
{
// in wParam l'errore Winsock
if(wParam!=0)
CSock::SetWSALastError(wParam);
CAsyncSock::OnAsyncGetServByPort((LPCSTR)lParam);
// invia il messaggio all'applicazione (controlla che sia stata specificata una finestra)
if(CSock::m_pParent)
CSock::m_pParent->PostMessage(WM_ASYNCGETSERVBYPORT,wParam,lParam);
return(0L);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -