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

📄 tcpserver.cpp

📁 Socketlib: 一个轻量级的C++ 封装Socket C API 网络编程框架。 它简化了Socket异步事件分派、进程间Socket通信的并发OO网络应用和服务的开发。 目前
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	SOCKADDR_IN InternetAddr;
	memset(&InternetAddr,0,sizeof(InternetAddr));
	InternetAddr.sin_family = AF_INET;
	InternetAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
	InternetAddr.sin_port = htons(nPort);
	if (bind(m_hListenSocket,(SOCKADDR*)&InternetAddr,sizeof(InternetAddr)) == SOCKET_ERROR)
	{
#ifdef SHOW_PRINTFINFO
		printf("TcpServer bind socket failure!\r\n");
#else
	#ifdef SOCKETLIB_WRITE_LOG
		m_pAppLog->WriteLog("TcpServer bind socket failure!", __FILE__, __LINE__, CAppLog::LOG_LEVEL_7);
	#endif
#endif
		return false;
	}

	//侦听端口上的连接请求
	if ( listen(m_hListenSocket,nBacklog) == SOCKET_ERROR )
	{
#ifdef SHOW_PRINTFINFO
		printf("Listening socket failure!\r\n");
#else
	#ifdef SOCKETLIB_WRITE_LOG
		m_pAppLog->WriteLog("Listening socket failure!", __FILE__, __LINE__, CAppLog::LOG_LEVEL_7);
	#endif
#endif
		return false;
	}

	//创建空闲Soket的内存池
	for (int i=0; i<m_nDefaultFreePoolNum; i++)
	{
		//分配IO操作数据的内存
		char *p = (char*)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 
			(sizeof(SOCKET_SESSION)+m_nRecvBufferSize) );
		if (NULL == p)
		{
			return false;
		}
		PSOCKET_SESSION pSocketSession = (PSOCKET_SESSION)p;
		pSocketSession->PerHandle.hSocket		= 0;
		pSocketSession->PerHandle.pSocketSource = this;
		pSocketSession->PerIoRecv.szDataBuffer  = (p+sizeof(SOCKET_SESSION));
		InitializeCriticalSection(&(pSocketSession->PerIoSend.IoLock));
		m_lstFreePool.push_back(pSocketSession);
	}
	m_bIsStart = true;

	//启动侦听线程
	m_threadListen.Start(CTcpServer::ListenProc,this,false);

#ifdef SHOW_PRINTFINFO
	printf("TcpServer::Open success, socket:%ld port:%d!\r\n", m_hListenSocket, nPort);
#else
#ifdef SOCKETLIB_WRITE_LOG
	SL_TCHAR szLog[MAX_LOGBUFFER_LENGTH]={0};
	_stprintf(szLog, TEXT("TcpServer::Open success, socket:%ld port:%d!"), m_hListenSocket, nPort);
	m_pAppLog->WriteLog(szLog, __FILE__, __LINE__, CAppLog::LOG_LEVEL_7);
#endif
#endif

	return true;
}

bool CTcpServer::Close()
{
	m_bIsStart = false;
	if (m_hListenSocket == NULL)
		return false;

	//关闭网络的侦听
	shutdown(m_hListenSocket,0);
	closesocket(m_hListenSocket);
	m_hListenSocket = NULL;

	m_threadListen.Stop(100);
	m_threadListen.Kill();

	//清除在线Socket
	std::map<SOCKET,PSOCKET_SESSION>::iterator itClientSocket;
	for (itClientSocket = m_mapSocketSession.begin(); itClientSocket != m_mapSocketSession.end(); itClientSocket++)
	{
		shutdown(itClientSocket->first,SD_BOTH);
		closesocket(itClientSocket->first);
		DeleteCriticalSection(&(itClientSocket->second->PerIoSend.IoLock));
		HeapFree(GetProcessHeap(),0,(void*)itClientSocket->second);
	}
	m_mapSocketSession.clear();

	//清除空闲池
	std::list<PSOCKET_SESSION>::iterator itItem;
	for (itItem = m_lstFreePool.begin(); itItem != m_lstFreePool.end(); itItem++)
	{
		DeleteCriticalSection(&((*itItem)->PerIoSend.IoLock));
		HeapFree(GetProcessHeap(),0,*itItem);
	}
	m_lstFreePool.clear();

#ifdef SHOW_PRINTFINFO
	printf("TcpServer::Close()!\r\n");
#else
#ifdef SOCKETLIB_WRITE_LOG
	m_pAppLog->WriteLog("TcpServer::Close()!", __FILE__, __LINE__, CAppLog::LOG_LEVEL_7);
#endif
#endif

	return true;
}

inline bool CTcpServer::Disconnect(SOCKET hClientSocket, bool bForce)
{
	if ( (hClientSocket==INVALID_SOCKET) || (hClientSocket==0) )
	{
		return false;
	}
	void *pAttachInfo = NULL;

	//取得Socket操作数据
	EnterCriticalSection(&m_lock);
	std::map<SOCKET,PSOCKET_SESSION>::iterator itClientSocket;
	itClientSocket = m_mapSocketSession.find(hClientSocket);
	if ( itClientSocket == m_mapSocketSession.end() )
	{
		LeaveCriticalSection(&m_lock);
		return false;
	}
	PSOCKET_SESSION pSocketSession = itClientSocket->second;
	pAttachInfo = pSocketSession->PerHandle.pAttachInfo;

	char   szIPAddr[MAX_IPADDR_LENGTH]={0};
	USHORT nPort = 0;
	CSocketAPI::GetSocketInfo(hClientSocket, szIPAddr, &nPort);
#ifdef SHOW_PRINTFINFO
	printf("ListenSocket:%ld, socket:%ld, clientip:%s, client close; tootal:%ld\r\n", 
		m_hListenSocket, hClientSocket, szIPAddr, m_mapSocketSession.size()-1 );
#else
#ifdef SOCKETLIB_WRITE_LOG
	char szLog[MAX_LOGBUFFER_LENGTH];
	sprintf(szLog, "ListenSocket:%ld, socket:%ld, clientip:%s, client close; tootal:%ld", 
		m_hListenSocket, hClientSocket, szIPAddr, m_mapSocketSession.size()-1 );
	m_pAppLog->WriteLog(szLog, __FILE__, __LINE__, CAppLog::LOG_LEVEL_5);
#endif
#endif

	//关闭套接字
	shutdown(hClientSocket,SD_BOTH);
	closesocket(hClientSocket);

	if (m_lstFreePool.size() >= m_nMaxFreePoolNum)
	{
		DeleteCriticalSection(&(pSocketSession->PerIoSend.IoLock));
		HeapFree(GetProcessHeap(),0,(void*)pSocketSession);
	}
	else
	{
		m_lstFreePool.push_back(pSocketSession);
	}
	m_mapSocketSession.erase(hClientSocket);
	LeaveCriticalSection(&m_lock);

	if (!bForce)
		m_pSocketEvent->OnDisconnect(this, hClientSocket, pAttachInfo);

	return true;
}

inline int CTcpServer::Recv(SOCKET hClientSocket, void *pAttachInfo, const char *szData, int nLen)
{
	return m_pSocketEvent->OnRecv(this, hClientSocket, pAttachInfo, szData, nLen);
}

int CTcpServer::Send(SOCKET hClientSocket, const char *szData, int nLen)
{
	//if ( (hClientSocket==INVALID_SOCKET) || (szData==NULL) || (nLen<=0) || (!m_bIsStart) )
	//{
	//	return -1;
	//}

	//取得Socket操作数据
	EnterCriticalSection(&m_lock);
	std::map<SOCKET,PSOCKET_SESSION>::iterator itClientSocket;
	itClientSocket = m_mapSocketSession.find(hClientSocket);
	if ( itClientSocket == m_mapSocketSession.end() )
	{
		LeaveCriticalSection(&m_lock);
		return -1;
	}
	LeaveCriticalSection(&m_lock);
	PSOCKET_SESSION pSocketSession = itClientSocket->second;
	EnterCriticalSection(&(pSocketSession->PerIoSend.IoLock));

	//重置缓冲区
	DWORD nFlag = 0;
	DWORD nSendByte = 0;
	ZeroMemory(&(pSocketSession->PerIoSend.Overlapped),sizeof(OVERLAPPED));
	pSocketSession->PerIoSend.SocketBuf.buf = (char*)szData;
	pSocketSession->PerIoSend.SocketBuf.len = nLen;
	pSocketSession->PerIoSend.OperType = SEND_POSTED;
	int nRet = WSASend(hClientSocket,&(pSocketSession->PerIoSend.SocketBuf),1,
		&nSendByte,nFlag,&(pSocketSession->PerIoSend.Overlapped),NULL);

	LeaveCriticalSection(&(pSocketSession->PerIoSend.IoLock));
	if ( nRet==SOCKET_ERROR )
	{
		int nErrorID = WSAGetLastError();
		if (nErrorID != WSA_IO_PENDING)
		{//发送失败,最有可能是Socket已断开,所以按断开处理
			Disconnect(pSocketSession->PerHandle.hSocket);
#ifdef SHOW_PRINTFINFO
			printf("TcpServer::Send error:%ld, ListenSocket:%ld! \r\n", nErrorID, m_hListenSocket);
#else
	#ifdef SOCKETLIB_WRITE_LOG 
			char   szLog[MAX_LOGBUFFER_LENGTH];
			sprintf(szLog,"TcpServer::Send error:%ld, ListenSocket:%ld!",nErrorID, m_hListenSocket);
			m_pAppLog->WriteLog(szLog, __FILE__, __LINE__, CAppLog::LOG_LEVEL_7);
	#endif
#endif
			return -1;
		}
	}
	return nSendByte;
}

inline bool CTcpServer::IsConnected(SOCKET hClientSocket)
{
	EnterCriticalSection(&m_lock);
	std::map<SOCKET,PSOCKET_SESSION>::iterator itClientSocket;
	itClientSocket = m_mapSocketSession.find(hClientSocket);
	if ( itClientSocket == m_mapSocketSession.end() )
	{
		LeaveCriticalSection(&m_lock);
		return false;
	}
	LeaveCriticalSection(&m_lock);
	return true;
}

inline bool CTcpServer::SetAttachInfo(SOCKET hClientSocket, void *pAttachInfo)
{
	EnterCriticalSection(&m_lock);
	std::map<SOCKET,PSOCKET_SESSION>::const_iterator itClientSocket;
	itClientSocket = m_mapSocketSession.find(hClientSocket);
	if ( itClientSocket == m_mapSocketSession.end() )
	{
		LeaveCriticalSection(&m_lock);
		return false;
	}
	PSOCKET_SESSION pSocketSession = (*itClientSocket).second;
	pSocketSession->PerHandle.pAttachInfo = pAttachInfo;
	LeaveCriticalSection(&m_lock);
	return false;
}

void* CTcpServer::GetAttachInfo(SOCKET hClientSocket)
{
	EnterCriticalSection(&m_lock);
	std::map<SOCKET,PSOCKET_SESSION>::iterator itClientSocket;
	itClientSocket = m_mapSocketSession.find(hClientSocket);
	if ( itClientSocket == m_mapSocketSession.end() )
	{
		LeaveCriticalSection(&m_lock);
		return NULL;
	}
	PSOCKET_SESSION pSocketSession = (*itClientSocket).second;
	LeaveCriticalSection(&m_lock);
	return pSocketSession->PerHandle.pAttachInfo;
}

}

⌨️ 快捷键说明

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