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

📄 wzdsock.cpp

📁 E:Visual_C__MFC扩展编程实例 实例51:使用套接字与任意的应用程序通信
💻 CPP
字号:
// WzdSock.cpp: implementation of the CWzdServer and CWzdClient classes.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "WzdSock.h"

//////////////////////////////////////////////////////////////////////
// CWzdServer
//////////////////////////////////////////////////////////////////////

/////////////////////////
// Cleanup
/////////////////////////

CWzdServer::~CWzdServer()
{
	// cleanup all created sockets
	int id;
	CSocket *pSocket;
	for (POSITION pos = m_mapSockets.GetStartPosition(); pos;)
	{
		m_mapSockets.GetNextAssoc(pos,id,pSocket);
		delete pSocket;
	}
}

/////////////////////////
// Open Socket
/////////////////////////

BOOL CWzdServer::Open(UINT nPort)
{
	return Create(nPort);
}
 
/////////////////////////
// Send to Socket
/////////////////////////

void CWzdServer::SendEx(int id, LPSTR lpBuf, int len)
{
	// locate the socket for this id
	CSocket *pSocket=m_mapSockets[id];
	if (pSocket)
	{
		m_SendData.pSocket=pSocket;
		m_SendData.lpBuf=lpBuf;
		m_SendData.len=len;

		// start the thread
		AfxBeginThread(SendThread,&m_SendData);
	}
}

/////////////////////////
// Listen to Socket
/////////////////////////

void CWzdServer::ListenEx(int hdrSz, int bodyPos, CWzdQueue *pQueue, CWnd *pWnd, UINT id)
{
	// initialize receive data 
	m_RecvData.hdrSz=hdrSz;
	m_RecvData.bodyPos=bodyPos;
	m_RecvData.pQueue=pQueue;
	m_RecvData.pWnd=pWnd;
	m_id=id; //starting id

 	// start listening
 	Listen();
}

// Listen() calls OnAccept() when a new client is attempting to connect 
void CWzdServer::OnAccept ( int nErrorCode )
{
	if (nErrorCode==0)
	{
		// create a new socket and add to map
 		CSocket *pSocket= new CSocket;
		m_mapSockets[m_id]=pSocket;

		// use this new socket to connect to client
 		Accept((CAsyncSocket&)*pSocket);

		// put socket into synchronous mode
		DWORD arg=0;
		pSocket->AsyncSelect(0); 
		pSocket->IOCtl( FIONBIO, &arg );

		// setup this socket to listen for client messages
		m_RecvData.pSocket=pSocket;
		m_RecvData.id=m_id++;

		// start the thread
		AfxBeginThread(RecvThread,&m_RecvData);
	}
}

/////////////////////////
// Close Sockets
/////////////////////////

void CWzdServer::CloseEx()
{
	int id;
	CSocket *pSocket;
	for (POSITION pos = m_mapSockets.GetStartPosition(); pos;)
	{
		m_mapSockets.GetNextAssoc(pos,id,pSocket);
		pSocket->Close();
	}
	Close();

}

//////////////////////////////////////////////////////////////////////
// CWzdClient
//////////////////////////////////////////////////////////////////////

/////////////////////////
// Open Socket
/////////////////////////

BOOL CWzdClient::Open(LPCTSTR lpszHostAddress, UINT nHostPort)
{
	if (Create() && Connect(lpszHostAddress, nHostPort))
	{
		// put socket into synchronous mode
		DWORD arg=0;
		AsyncSelect(0); 
		IOCtl( FIONBIO, &arg );
		return TRUE;
	}
	return FALSE;
}
 
/////////////////////////
// Send to Socket
/////////////////////////

void CWzdClient::SendEx(LPSTR lpBuf, int len)
{
	// initialize the structure we will pass to thread
	m_SendData.pSocket=this;
	m_SendData.lpBuf=lpBuf;
	m_SendData.len=len;

	// start the thread
	AfxBeginThread(SendThread,&m_SendData);
}


/////////////////////////
// Listen to Socket
/////////////////////////

void CWzdClient::ListenEx(int hdrSz, int bodyPos, CWzdQueue *pQueue, CWnd *pWnd, UINT id)
{
	// initialize receive data 
	m_RecvData.pSocket=this;
	m_RecvData.hdrSz=hdrSz;
	m_RecvData.bodyPos=bodyPos;
	m_RecvData.pQueue=pQueue;
	m_RecvData.pWnd=pWnd;
	m_RecvData.id=id;

	// start the thread
	AfxBeginThread(RecvThread,&m_RecvData);
}


//////////////////////////////////////////////////////////////////////
// Threads
//////////////////////////////////////////////////////////////////////

UINT SendThread( LPVOID pParam )
{
	// get data from thread creator
	SENDDATA *pSend=(SENDDATA *)pParam;

	// do the write
 	pSend->pSocket->Send( pSend->lpBuf, pSend->len);

	return 0;
}


UINT RecvThread( LPVOID pParam )
{
	// get data from thread creator
	RECVDATA *pRecv=(RECVDATA *)pParam;

	int len=1;
	int error=0;
	char *pBody=NULL;
	char *pHdr=NULL;
	// while both sockets are open
	while (TRUE)
	{
		// read the header
		int res;
		pBody=NULL;
		pHdr=new char[pRecv->hdrSz];
		if ((res=pRecv->pSocket->CAsyncSocket::Receive( pHdr, pRecv->hdrSz))==SOCKET_ERROR)
			error=::GetLastError();
		else
			len=res;

		// if closing down, exit thread
		if (len==0 || error==WSAECONNRESET || error==WSAECONNABORTED) break;

		// read the body???
		if (!error && len && pRecv->bodyPos!=-1)
		{
			int bodyLen=*((short *)pHdr+pRecv->bodyPos);
			pBody=new char[bodyLen];
			if ((res=pRecv->pSocket->CAsyncSocket::Receive( pBody, bodyLen ))==SOCKET_ERROR)
				error=::GetLastError();
			else
				len+=res;

			// if closing down, exit thread
			if (len==0 || error==WSAECONNRESET || error==WSAECONNABORTED) break;
		}

		// put message in queue
		pRecv->pQueue->Add(new CWzdMsg(pRecv->id,pHdr,pBody,len,error));

		// post message to window to process this new message
		pRecv->pWnd->PostMessage(WM_NEW_MESSAGE);

	}

	// cleanup anything we started
	delete []pHdr;
	delete []pBody;

	// tell somebody we stopped
	pRecv->pWnd->SendMessage(WM_DONE_MESSAGE,(WPARAM)pRecv->id,(LPARAM)error);

	return 0;
}

⌨️ 快捷键说明

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