tcp_socket.cpp

来自「网络泡泡被.net管理」· C++ 代码 · 共 533 行

CPP
533
字号
   // TCP_Socket.cpp: implementation of the TCP_Socket class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TCP.h"
#include <stdio.h>
#include <stdlib.h>

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////


TCP_Socket::TCP_Socket()
{
	m_socket	= INVALID_SOCKET;

	m_uid_lmt_min		= 1;
	m_uid_lmt_max		= 100000;
	INIT_CS(&m_lock_map_session);
}

TCP_Socket::~TCP_Socket()
{
	Shutdown();
	DELETE_CS(&m_lock_map_session);
}




bool TCP_Socket::LockSessionMap()
{
	LOCK_CS(&m_lock_map_session);
	return true;
}

void TCP_Socket::UnlockSessionMap()
{
	UNLOCK_CS(&m_lock_map_session);
}


VOID TCP_Socket::Shutdown()
{
//	if(m_thread_transfers!=NULL)
//	{//wait for thread end
//		m_wait_thread_end	= true;
//		while(m_wait_thread_end)
//		{
//			Sys_Sleep(100);
//		}
//	}
	m_thread_pool.Cleanup();

	CleanupSessionMap();
	CleanupRecvList();
//	CleanupSendList();

	if(m_socket!=INVALID_SOCKET)
	{
		CLOSESOCKET(m_socket);

		m_socket	= INVALID_SOCKET;
	}
}

bool TCP_Socket::Create(uint16 port, uint32 uid_limit_min, uint32 uid_limit_max)
{
	if(m_socket!=INVALID_SOCKET)
		Shutdown();
	m_socket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
	if (m_socket < 0) 
	{
		Sys_Log("net_lib_log", "create tcp socket failed." );
		return false;
	}

	sockaddr_in addr;
	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_port = htons(port);
	addr.sin_addr.s_addr = INADDR_ANY;
	if (bind(m_socket, (sockaddr *) &addr, sizeof(addr)) < 0) 
	{
		Sys_Log("net_lib_log", "tcp socket bind failed." );
		closesocket(m_socket);
		m_socket	= 0;
		return false;
	}

	m_uid_lmt_min	= uid_limit_min;
	m_uid_lmt_max	= uid_limit_max;

//	ThreadInit();


	return true;
}

TCP_Session* TCP_Socket::get_TCP_Session(uint32 uid)
{
	LOCK_CS(&m_lock_map_session);
	TCP_Session* pRet;
	std::map<uint32, TCP_Session*>::iterator it = m_map_session.find(uid);
	if(it!=m_map_session.end())
		pRet = it->second;
	else
		pRet = NULL;
	UNLOCK_CS(&m_lock_map_session);
	return pRet;
}

NET_Session* TCP_Socket::get_NET_Session(uint32 uid)
{
	return get_TCP_Session(uid);
}




TCP_Session* TCP_Socket::CreateSession(uint32 ip, uint16 port, const char* szAddr)
{
	TCP_Session* pRet	= NULL;
	LOCK_CS(&m_lock_map_session);
	int size = m_map_session.size();
	UNLOCK_CS(&m_lock_map_session);
	if(size<=m_uid_lmt_max - m_uid_lmt_min)
	{
		//获取唯一的id
		LOCK_CS(&m_lock_map_session);
		uint32 uid = m_uid_lmt_min;
		while(m_map_session.find(uid)!=m_map_session.end())
		{
			uid++;
			if(uid>m_uid_lmt_max)
			{
				uid=0;
			}
		}
		UNLOCK_CS(&m_lock_map_session);

		if(uid>0)
		{
			if(ip==0 && port==0)
			{//accept a connect
				if(!NET_CanRead(m_socket))
					return NULL;
				pRet	= new TCP_Session(uid, this);
				if(pRet==NULL)
					return NULL;
				int len = sizeof(pRet->m_addr_in);
				pRet->m_socket = accept(m_socket, (SOCKADDR *)&(pRet->m_addr_in), (socklen_t *)&len);
				if (pRet->m_socket == INVALID_SOCKET || pRet->m_socket == NULL)
				{
					delete(pRet);
					Sys_Log("net_lib_log", "accept error");
					return NULL;
				}
				pRet->RunTransfersThread();
				LOCK_CS(&m_lock_map_session);
				m_map_session[uid]	= pRet;
				UNLOCK_CS(&m_lock_map_session);
				pRet->NET_Session::Connect();
			}
			else
			{//make connect

				pRet	= new TCP_Session(uid, this);
				if(pRet==NULL)
					return NULL;
				sockaddr_in*	p_addr =	pRet->get_sockaddr_in();
				memset(p_addr, 0, sizeof(sockaddr_in));
				p_addr->sin_family = AF_INET;
//				p_addr->sin_addr.s_addr = htonl(ip);
				p_addr->sin_port = htons(port);



				if(szAddr)
					p_addr->sin_addr.s_addr = inet_addr(szAddr);
				else
					p_addr->sin_addr.s_addr = htonl(ip);
				
				if(p_addr->sin_addr.s_addr==INADDR_NONE)
				{
					hostent *host=NULL;
					if(!szAddr) 
					{
						delete(pRet);
						return NULL;
					}
					host=gethostbyname(szAddr);
					if(!host) 
					{
						delete(pRet);
						return NULL;
					}
					memcpy(&p_addr->sin_addr,host->h_addr_list[0],host->h_length);
				}
				
//				if(connect(pRet->m_socket,(SOCKADDR *)p_addr,sizeof(pRet->m_addr_in))
//					==SOCKET_ERROR)
//				{
//					int err = GETERROR;
//					if (err != CONN_INPRROGRESS)
//					{
//						Sys_Log("net_lib_log", "socket connect error = %d",err); 
//						delete(pRet);
//						return false;
//					}
//				}
//				pRet->RunTransfersThread();
				LOCK_CS(&m_lock_map_session);
				m_map_session[uid]	= pRet;
				UNLOCK_CS(&m_lock_map_session);
//				pRet->Connect();
			}
			pRet->time_set(Sys_GetTime());
		}

	}


	return pRet;
}

TCP_Session* TCP_Socket::CreateSession(sockaddr_in *ptr_addr)
{
	if(NULL==ptr_addr)
	{
		return CreateSession(0,0);
	}
	return CreateSession(ntohl(ptr_addr->sin_addr.s_addr), ntohs(ptr_addr->sin_port));
}

TCP_Session* TCP_Socket::CreateUniqueSession(uint32 ip, uint16 port, uint32 uid_unique, const char* szAddr)
{
	LOCK_CS(&m_lock_map_session);
	if(m_map_session.find(uid_unique)!=m_map_session.end())
	{
		UNLOCK_CS(&m_lock_map_session);
		return false;
	}
	UNLOCK_CS(&m_lock_map_session);


	TCP_Session*	pRet;
	if(ip==0 && port==0)
	{//accept a connect
		if(!NET_CanRead(m_socket))
			return NULL;
		pRet	= new TCP_Session(uid_unique, this);
		if(pRet==NULL)
			return NULL;
		int len = sizeof(pRet->m_addr_in);
		pRet->m_socket = accept(m_socket, (SOCKADDR *)&(pRet->m_addr_in), (socklen_t *)&len);
		if (pRet->m_socket == INVALID_SOCKET || pRet->m_socket == NULL)
		{
			delete(pRet);
			Sys_Log("net_lib_log", "accept error");
			return NULL;
		}
		pRet->RunTransfersThread();
		LOCK_CS(&m_lock_map_session);
		m_map_session[uid_unique]	= pRet;
		UNLOCK_CS(&m_lock_map_session);
		pRet->NET_Session::Connect();
	}
	else
	{//make connect
		
		pRet	= new TCP_Session(uid_unique, this);
		if(pRet==NULL)
			return NULL;
		sockaddr_in*	p_addr =	pRet->get_sockaddr_in();
		memset(p_addr, 0, sizeof(sockaddr_in));
		p_addr->sin_family = AF_INET;
		p_addr->sin_port = htons(port);
		
		if(szAddr)
			p_addr->sin_addr.s_addr = inet_addr(szAddr);
		else
			p_addr->sin_addr.s_addr = htonl(ip);
		
		if(p_addr->sin_addr.s_addr==INADDR_NONE)
		{
			hostent *host=NULL;
			if(!szAddr) 
			{
				delete(pRet);
				return NULL;
			}
			host=gethostbyname(szAddr);
			if(!host) 
			{
				delete(pRet);
				return NULL;
			}
			memcpy(&p_addr->sin_addr,host->h_addr_list[0],host->h_length);
		}
		
//		if(connect(pRet->m_socket,(SOCKADDR *)p_addr,sizeof(pRet->m_addr_in))
//			==SOCKET_ERROR)
//		{
//			int err = GETERROR;
//			if (err != CONN_INPRROGRESS)
//			{
//				Sys_Log("net_lib_log", "socket connect error = %d",err); 
//				delete(pRet);
//				return false;
//			}
//		}
//		pRet->RunTransfersThread();
		LOCK_CS(&m_lock_map_session);
		m_map_session[uid_unique]	= pRet;
		UNLOCK_CS(&m_lock_map_session);

//		pRet->Connect();
	}		
	pRet->time_set(Sys_GetTime());

	return pRet;
	
}

void TCP_Socket::CloseSession(uint32 uid)
{
	TCP_Session* pSession = NULL;
	LOCK_CS(&m_lock_map_session);
	std::map<uint32, TCP_Session*>::iterator it = m_map_session.find(uid);
	if(it!=m_map_session.end())
	{
		pSession = it->second;
		m_map_session.erase(it);
	}
	UNLOCK_CS(&m_lock_map_session);
	if(pSession)
		m_thread_pool.RunThread(NULL, thread_close_session, pSession);
}





void TCP_Socket::ThreadEnd()
{
//	DELETE_CS(&m_lock_map_session);
//	DELETE_CS(&m_lock_recv_packet);
//	DELETE_CS(&m_lock_send_packet);
//	m_thread_transfers	= NULL;
}

void TCP_Socket::ThreadInit()
{
//	INIT_CS(&m_lock_map_session);
//	INIT_CS(&m_lock_recv_packet);
//	INIT_CS(&m_lock_send_packet);

}

int TCP_Socket::GetSessionCount()
{
	return m_map_session.size();
}


void TCP_Socket::CleanupSessionMap()
{
	LOCK_CS(&m_lock_map_session);
	std::map<uint32, TCP_Session*>::iterator it = m_map_session.begin();
	while(it!=m_map_session.end())
	{
		TCP_Session* pSession = it->second;
		UNLOCK_CS(&m_lock_map_session);
		if(pSession)
		{
			pSession->Disconnect();
			delete(pSession);
		}
		m_map_session.erase(it);
		LOCK_CS(&m_lock_map_session);
		it = m_map_session.begin();
	}
	UNLOCK_CS(&m_lock_map_session);

}



uint32 TCP_Socket::getIP()
{

	return 0;
}

uint16 TCP_Socket::getPort()
{

	return 0;
}


void TCP_Socket::CheckConnect(time_t time)
{
	if(m_socket<=0)
		return;
	LOCK_CS(&m_lock_map_session);
	std::map<uint32, TCP_Session*>::iterator it = m_map_session.begin();
	while(it!=m_map_session.end())
	{
		if(it->second)
		{
			it->second->Check_connect(Sys_GetTime());
		}
		it++;
	}
	UNLOCK_CS(&m_lock_map_session);
}



bool		TCP_Socket::PushRecvPacket(NET_Packet* ptr_packet, time_t time)
{
	if(ptr_packet==NULL)
		return false;

	//在这里处理被动连接
//	if(ptr_packet->getCmd()==NLIBP_CONNECT)
//	{
//		TCP_Session* pSession = get_TCP_Session(ptr_packet->getUID());
//		uint32 uid	= ptr_packet->read32();
//		if(pSession)
//		{//已连接,是连接确认信息
//			pSession->time_set(time);
//			if(pSession->m_uid_opposite==0)
//				pSession->m_uid_opposite	= uid;
//		}
//		delete(ptr_packet);
//		return true;
//	}

	return NET_Socket::PushRecvPacket(ptr_packet, time);
}

NET_Packet*	TCP_Socket::PopRecvPacket()
{

	return NET_Socket::PopRecvPacket();
}



bool TCP_Socket::PushSendPacket(uint32 uid_sendto, NET_Packet* ptr_packet)
{
	NET_Session*	pSession	= get_NET_Session(uid_sendto);
	if(pSession==NULL)
	{
		delete(ptr_packet);
		return false;
	}
	return pSession->PushSendPacket(ptr_packet);
}




bool TCP_Socket::change_session_uid(uint32 uid, uint32 uid_to)
{
	LOCK_CS(&m_lock_map_session);
	std::map<uint32, TCP_Session*>::iterator it = m_map_session.find(uid_to);
	if(it!=m_map_session.end())
	{//the id want is belong to others!
		UNLOCK_CS(&m_lock_map_session);
		return false;
	}

	it	= m_map_session.find(uid);
	if(it==m_map_session.end())
	{
		UNLOCK_CS(&m_lock_map_session);
		return false;
	}
	else
	{
		TCP_Session* pSession	= it->second;
		if(pSession==NULL)
		{
			UNLOCK_CS(&m_lock_map_session);
			return false;
		}
		m_map_session.erase(it);
		pSession->m_uid	= uid_to;
		m_map_session[uid_to]	= pSession;
	}

	UNLOCK_CS(&m_lock_map_session);

	return true;
}

bool TCP_Socket::RunTransfersThread()
{
	if(false==m_thread_pool.RunThread("listen_thread", thread_TCP_listen, this))
		return false;

	return true;
}

void TCP_Socket::Ping(uint32 uid)
{
	if(uid==0)
	{
		LOCK_CS(&m_lock_map_session);
		std::map<uint32, TCP_Session*>::iterator it = m_map_session.begin();
		while(it!=m_map_session.end())
		{
			if(it->second)
				it->second->Ping();
			it++;
		}
		UNLOCK_CS(&m_lock_map_session);
	}
	else
	{
		NET_Session*	pSession = get_NET_Session(uid);
		if(pSession)
			pSession->Ping();
	}

}

⌨️ 快捷键说明

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