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

📄 tcpsocket.cpp

📁 AsynSocketDemo.rar网络代码,可以设置代理,ssl加密. AsynSocketDemo.rar网络代码,可以设置代理,ssl加密. AsynSocketDemo.rar网络代码,
💻 CPP
字号:
#include "StdAfx.h"
#include ".\tcpsocket.h"



CTcpSvrSocket::CTcpSvrSocket(int nListenPort,ITcpSocketUpper *pTSU)
{
	m_pTSU = pTSU;
	m_nListenPort = nListenPort;
	
	m_hThread = NULL;
	m_nThreadState = STOP;

	int nErr;
	WSADATA WsaData;
	nErr = WSAStartup (0x0202, &WsaData);
	if (nErr == SOCKET_ERROR)
	{
		//printf( "WSAStartup Failed\n");
		return;
	}
}

CTcpSvrSocket::~CTcpSvrSocket(void)
{
	WSACleanup();
}
int WINAPI CTcpSvrSocket::SendData(char *pData,int len,int socketId)
{
	if( socketId < 0 || NULL == pData || len < 0 )
		return -1;
	memset(pData+len,0,1);
	return send(socketId,pData,len,0);
	//LPWSAOVERLAPPEDEX	lpOvlpEx;
	//lpOvlpEx = (WSAOVERLAPPEDEX *) GlobalAlloc(GPTR,sizeof(WSAOVERLAPPEDEX));
	//ZeroMemory(lpOvlpEx,sizeof(WSAOVERLAPPED));
	//lpOvlpEx->WSABuf.len = len;
	//lpOvlpEx->WSABuf.buf = pData;
	//DWORD dwRecvBytes = 0,dwFlags = 0;

	//
	//if ( WSASend(socketId,&lpOvlpEx->WSABuf,1,&dwRecvBytes,dwFlags,(LPWSAOVERLAPPED)lpOvlpEx,NULL) == SOCKET_ERROR)
	//{
	//	if ( WSAGetLastError() != WSA_IO_PENDING)
	//	{
	//		SafeClose(lpOvlpEx);
	//	}
	//}
	//GlobalFree(lpOvlpEx);
	//return 0;
}
void CTcpSvrSocket::Start()
{
	DWORD dwThreadID;
	m_nThreadState = RUNNIG; 
	m_hThread = CreateThread(NULL,0,MainThread,(LPVOID)this,0,&dwThreadID);
	if (m_hThread != NULL)
	{
		m_nThreadState = RUNNIG;
	}
	else
	{
		m_nThreadState = STOP;
	}
}
void CTcpSvrSocket::Stop()
{
	m_nThreadState = STOP;
}
DWORD WINAPI CTcpSvrSocket::ServerWorkerThread(LPVOID p)
{
	CTcpSvrSocket *pTSS = (CTcpSvrSocket *)p;
	HANDLE hCompletionPort = pTSS->m_hCompletionPort;
	DWORD  dwBytesTransferred = 0;
	SOCKET hSocket; 
	LPWSAOVERLAPPEDEX	lpOvlpEx;
	int nErr;
	sockaddr_in destaddr;
	int len = sizeof(sockaddr_in);

	while (1)
	{
		BOOL r = GetQueuedCompletionStatus(hCompletionPort,&dwBytesTransferred,(LPDWORD)&hSocket,(LPWSAOVERLAPPED *) &lpOvlpEx,INFINITE );
		if (!r)
		{
			nErr = WSAGetLastError();
			//printf("GetQueuedCompletionStatus = %d\n",nErr);
		}
		
		if (hSocket == 0 || lpOvlpEx == NULL)
			break;

		getsockname( hSocket,(sockaddr *)&destaddr,&len);
		//printf("%d bytes transed...\n",dwBytesTransferred);

		if (dwBytesTransferred == 0)
		{
			if (hSocket == lpOvlpEx->hSocket)
			{
				pTSS->SafeClose(lpOvlpEx);
				//printf(" .....................%d..........closed & freed........\n",hSocket);			
			}

			continue;
		}
		
		pTSS->m_pTSU->OnRecvData( lpOvlpEx->Buffer,dwBytesTransferred,destaddr,hSocket);
		if (hSocket == lpOvlpEx->hSocket)
		{
			// todo ...

			DWORD dwRecvBytes = 0,dwFlags = 0;
			lpOvlpEx->WSABuf.len = DATA_BUFSIZE;
			ZeroMemory(lpOvlpEx,sizeof(WSAOVERLAPPED));
		
			if ( WSARecv(lpOvlpEx->hSocket,&lpOvlpEx->WSABuf,1,&dwRecvBytes,&dwFlags,(LPWSAOVERLAPPED)lpOvlpEx,NULL) == SOCKET_ERROR)
			{
				if ( WSAGetLastError() != WSA_IO_PENDING)
				{
					//printf("%d recv err = %d\n",lpOvlpEx->hSocket,WSAGetLastError());
					if( NULL !=pTSS->m_pTSU )
						pTSS->m_pTSU->OnClose( hSocket,destaddr );
					pTSS->SafeClose(lpOvlpEx);
					continue;
				}
			}
		
		}
	
		
	
	}
	return 0;
}
DWORD WINAPI CTcpSvrSocket::MainThread(LPVOID pArgu)
{
	CTcpSvrSocket *pTSS = (CTcpSvrSocket *)pArgu;

	int nErr;
	
	HANDLE hCompletionPort = CreateIoCompletionPort (
		INVALID_HANDLE_VALUE,
		NULL,
		0,
		0
		);
	
	if (!hCompletionPort)
	{
		//printf( "CompletionPort Create Failed\n");
		return  -1;
	}
	
	pTSS->m_hCompletionPort = hCompletionPort;

	SYSTEM_INFO si;
	GetSystemInfo(&si);

	DWORD i = 0;
	for ( i = 0 ; i < THREAD_MAXNUM; i++ )
	{
		HANDLE hThread;
		DWORD dwThreadID;
		hThread = CreateThread(NULL,0,ServerWorkerThread,pTSS,0,&dwThreadID);
		
		//CloseHandle有无必要值得讨论,因为有时我们需要WaitForSingleObject(hThread,-1)来等待线程结束.
		//
		//CloseHandle(hThread);
	}
	
	
	
	SOCKADDR_IN localAddr;

	SOCKET hListener;

	hListener = WSASocket (AF_INET, SOCK_STREAM, 0,NULL,0,WSA_FLAG_OVERLAPPED);
	if (hListener == INVALID_SOCKET)
	{
		//printf( "Socket Create Failed\n");
		return -1;
	}
	
	//
	// Bind our server to the agreed upon port number.  See
	// commdef.h for the actual port number.
	//
	ZeroMemory (&localAddr, sizeof (localAddr));
	localAddr.sin_family = AF_INET;
	localAddr.sin_port = htons (pTSS->m_nListenPort);
	localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	nErr = bind (hListener, (PSOCKADDR) & localAddr, sizeof (localAddr));
	if (nErr == SOCKET_ERROR)
	{
		//printf( "Socket Bind Failed\n");
		if (WSAGetLastError () == WSAEADDRINUSE)
            //printf( "The port number may already be in use.\n");
		return -1;
	}
	nErr = listen (hListener, 5);
	if (nErr == SOCKET_ERROR)
	{
		//printf( "Socket Listen Failed\n");
		return -1;
	}

	SOCKET hAcceptSocket;
	while (pTSS->m_nThreadState == RUNNIG)
	{

		hAcceptSocket = WSAAccept(hListener,NULL,NULL,NULL,0);
		
		//线程绝大多数是等候在WSAAccept
		if (pTSS->m_nThreadState != RUNNIG)
		{
			closesocket(hAcceptSocket);
			break;
		}
		
		sockaddr_in destaddr;
		int len = sizeof( destaddr );
		getsockname( hAcceptSocket,(sockaddr *)&destaddr,&len);
		pTSS->m_pTSU->OnConnect( destaddr, hAcceptSocket );


		WSAOVERLAPPEDEX * pAcceptOvl = (WSAOVERLAPPEDEX *) GlobalAlloc(GPTR,sizeof(WSAOVERLAPPEDEX));
		if (pAcceptOvl == NULL)
		{
			closesocket(hAcceptSocket);
			//printf("accept %d error...\n",hAcceptSocket);
			continue;
		}

		//printf("=======================================Accept= %d \n",hAcceptSocket);
		//assert(pAccept);
		pAcceptOvl->pPair = NULL;
		pAcceptOvl->WSABuf.buf   = pAcceptOvl->Buffer;
		pAcceptOvl->WSABuf.len   = DATA_BUFSIZE;
		pAcceptOvl->hSocket = hAcceptSocket;
		pAcceptOvl->pTSS = (LPVOID)pTSS;
		CreateIoCompletionPort((HANDLE)hAcceptSocket,hCompletionPort,(DWORD)hAcceptSocket,0);
		//pAccept->Recv();
		DWORD dwRecvBytes = 0,dwFlags = 0;
		
		if ( WSARecv(hAcceptSocket,&pAcceptOvl->WSABuf,1,&dwRecvBytes,&dwFlags,(LPWSAOVERLAPPED)pAcceptOvl,NULL) == SOCKET_ERROR)
		{
			if ( WSAGetLastError() != WSA_IO_PENDING)
			{
				//printf("%d accept recv err = %d",hAcceptSocket,WSAGetLastError());
			}
		}

	}


//**************************
//如果一定要强制终止以获得请求的连接,打开下面的代码
/*
	for( i = 0 ; i < THREAD_MAXNUM ; i++)
	{
		PostQueuedCompletionStatus(hCompletionPort,0,0,0);
	}
*/
//*****************************
	CloseHandle(hCompletionPort);

	return 0;
}
void CTcpSvrSocket::SafeClose(LPWSAOVERLAPPEDEX lpOvlpEx)
{
	sockaddr_in destaddr;
	int len = sizeof( destaddr );
	getsockname( lpOvlpEx->hSocket,(sockaddr *)&destaddr, &len);

	this->m_pTSU->OnClose( lpOvlpEx->hSocket, destaddr );
	if ( NULL != lpOvlpEx->hSocket )
	{
		closesocket(lpOvlpEx->hSocket); //close自己
		GlobalFree(lpOvlpEx);//释放自己
	}
	
}















////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//client socket









CTcpCltSocket::CTcpCltSocket(int nListenPort,ITcpSocketUpper *pTSU)
{
	m_pTSU = pTSU;
	m_nListenPort = nListenPort;
	
	m_hThread = NULL;
	m_nThreadState = STOP;
	m_socket = 0;
	m_hCompletionPort = 0;

	int nErr;
	WSADATA WsaData;
	nErr = WSAStartup (0x0202, &WsaData);
	if (nErr == SOCKET_ERROR)
	{
		return;
	}
}

CTcpCltSocket::~CTcpCltSocket(void)
{
	WSACleanup();
}
int WINAPI CTcpCltSocket::SendData(char *pData,int len,int socketId)
{
	if( NULL == pData || len < 0 || NULL == m_socket )
		return -1;
	memset(pData+len,0,1);
	return send( this->m_socket, pData, len, 0);
}
bool CTcpCltSocket::Start(const char * ip, unsigned short port )
{
	DWORD dwThreadID;
	m_nThreadState = RUNNIG; 
	

	  m_hCompletionPort = CreateIoCompletionPort (
		INVALID_HANDLE_VALUE,
		NULL,
		0,
		0
		);
	
	if (!m_hCompletionPort)
	{
		return  false;
	}
	
	SYSTEM_INFO si;
	GetSystemInfo(&si);

	DWORD i = 0;
	for ( i = 0 ; i < THREAD_MAXNUM; i++ )
	{
		HANDLE hThread;
		DWORD dwThreadID;
		hThread = CreateThread( NULL, 0, ServerWorkerThread, this, 0, &dwThreadID);	
	}
	
	
	
	SOCKADDR_IN localAddr;

	m_socket = WSASocket (AF_INET, SOCK_STREAM, 0,NULL,0,WSA_FLAG_OVERLAPPED);
	if (m_socket == INVALID_SOCKET)
	{
		CloseHandle(m_hCompletionPort);
		m_hCompletionPort = NULL;
		return false;
	}
	
	ZeroMemory (&localAddr, sizeof (localAddr));
	localAddr.sin_family = AF_INET;
	localAddr.sin_port = htons (m_nListenPort);
	localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
	
	int nErr = bind (m_socket, (PSOCKADDR) & localAddr, sizeof (localAddr));
	if (nErr == SOCKET_ERROR)
	{
		closesocket(m_socket);
		CloseHandle(m_hCompletionPort);
		m_hCompletionPort = NULL;
		return false;
	}
	sockaddr_in sa;
	sa.sin_family = AF_INET;
	sa.sin_port = htons ( port );
	sa.sin_addr.s_addr = inet_addr( ip ) ;
	int salen = sizeof( sockaddr_in );
	if( 0 > connect( m_socket,(sockaddr *)&sa , salen) )
	{
		closesocket(m_socket);
		CloseHandle(m_hCompletionPort);
		m_hCompletionPort = NULL;
	}
	m_pTSU->OnConnect( sa, m_socket);

	WSAOVERLAPPEDEX * pAcceptOvl = (WSAOVERLAPPEDEX *) GlobalAlloc(GPTR,sizeof(WSAOVERLAPPEDEX));
	if (pAcceptOvl == NULL)
	{
		closesocket(m_socket);
		CloseHandle(m_hCompletionPort);
		m_hCompletionPort = NULL;
		return false;
	}

	pAcceptOvl->pPair = NULL;
	pAcceptOvl->WSABuf.buf   = pAcceptOvl->Buffer;
	pAcceptOvl->WSABuf.len   = DATA_BUFSIZE;
	pAcceptOvl->hSocket = m_socket;
	pAcceptOvl->pTSS = (LPVOID)this;
	CreateIoCompletionPort((HANDLE)m_socket,m_hCompletionPort,(DWORD)m_socket,0);
		//pAccept->Recv();
	DWORD dwRecvBytes = 0,dwFlags = 0;
		
	if ( WSARecv(m_socket,&pAcceptOvl->WSABuf,1,&dwRecvBytes,&dwFlags,(LPWSAOVERLAPPED)pAcceptOvl,NULL) == SOCKET_ERROR)
	{
		if ( WSAGetLastError() != WSA_IO_PENDING)
		{
			//printf("%d accept recv err = %d",hAcceptSocket,WSAGetLastError());
		}
	}	
}
void CTcpCltSocket::Stop()
{
	m_nThreadState = STOP;
	::Sleep( 200 );
	if( m_hCompletionPort )
		CloseHandle( m_hCompletionPort );
}
DWORD WINAPI CTcpCltSocket::ServerWorkerThread(LPVOID p)
{
	CTcpCltSocket *pTSS = (CTcpCltSocket *)p;
	HANDLE hCompletionPort = pTSS->m_hCompletionPort;
	DWORD  dwBytesTransferred = 0;
	SOCKET hSocket; 
	LPWSAOVERLAPPEDEX	lpOvlpEx;
	int nErr;
	sockaddr_in destaddr;
	int len = sizeof(sockaddr_in);

	while (1)
	{
		BOOL r = GetQueuedCompletionStatus(hCompletionPort,&dwBytesTransferred,(LPDWORD)&hSocket,(LPWSAOVERLAPPED *) &lpOvlpEx,INFINITE );
		if (!r)
		{
			nErr = WSAGetLastError();
			//printf("GetQueuedCompletionStatus = %d\n",nErr);
		}
		
		if (hSocket == 0 || lpOvlpEx == NULL)
			break;

		getsockname( hSocket,(sockaddr *)&destaddr,&len);
		//printf("%d bytes transed...\n",dwBytesTransferred);

		if (dwBytesTransferred == 0)
		{
			if (hSocket == lpOvlpEx->hSocket)
			{
				pTSS->SafeClose(lpOvlpEx);
				//printf(" .....................%d..........closed & freed........\n",hSocket);			
			}

			continue;
		}
		
		pTSS->m_pTSU->OnRecvData( lpOvlpEx->Buffer,dwBytesTransferred,destaddr,hSocket);
		if (hSocket == lpOvlpEx->hSocket)
		{
			// todo ...

			DWORD dwRecvBytes = 0,dwFlags = 0;
			lpOvlpEx->WSABuf.len = DATA_BUFSIZE;
			ZeroMemory(lpOvlpEx,sizeof(WSAOVERLAPPED));
		
			if ( WSARecv(lpOvlpEx->hSocket,&lpOvlpEx->WSABuf,1,&dwRecvBytes,&dwFlags,(LPWSAOVERLAPPED)lpOvlpEx,NULL) == SOCKET_ERROR)
			{
				if ( WSAGetLastError() != WSA_IO_PENDING)
				{
					//printf("%d recv err = %d\n",lpOvlpEx->hSocket,WSAGetLastError());
					if( NULL !=pTSS->m_pTSU )
						pTSS->m_pTSU->OnClose( hSocket,destaddr );
					pTSS->SafeClose(lpOvlpEx);
					continue;
				}
			}
		
		}
	
		
	
	}
	return 0;
}
void CTcpCltSocket::SafeClose(LPWSAOVERLAPPEDEX lpOvlpEx)
{
	sockaddr_in destaddr;
	int len = sizeof( destaddr );
	getsockname( lpOvlpEx->hSocket,(sockaddr *)&destaddr, &len);

	this->m_pTSU->OnClose( lpOvlpEx->hSocket, destaddr );
	if ( NULL != lpOvlpEx->hSocket )
	{
		closesocket(lpOvlpEx->hSocket); //close自己
		GlobalFree(lpOvlpEx);//释放自己
	}
	
}

⌨️ 快捷键说明

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