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

📄 casyncsock.cpp

📁 VC网络程序设计实例导航配套代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		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 + -