udp_socket.cpp

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

CPP
519
字号
            // UDP_Socket.cpp: implementation of the UDP_Socket class.
//
//////////////////////////////////////////////////////////////////////

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

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


UDP_Socket::UDP_Socket()
{
	m_socket	= INVALID_SOCKET;

	m_uid_lmt_min		= 1;
	m_uid_lmt_max		= 100000;

	INIT_CS(&m_lock_map_session);
	INIT_CS(&m_lock_send_packet);
}

UDP_Socket::~UDP_Socket()
{
	Shutdown();
	DELETE_CS(&m_lock_map_session);
	DELETE_CS(&m_lock_send_packet);
}








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

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


VOID UDP_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 UDP_Socket::Create(uint16 port, uint32 uid_limit_min, uint32 uid_limit_max)
{
	if(m_socket!=INVALID_SOCKET)
		Shutdown();
	m_socket = socket(AF_INET, SOCK_DGRAM, 0);
	if (m_socket < 0) {
		Sys_Log("net_lib_log", "create udp 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", "udp 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;
}

UDP_Session* UDP_Socket::get_UDP_Session(uint32 uid)
{
	LOCK_CS(&m_lock_map_session);
	UDP_Session* pRet;
	std::map<uint32, UDP_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* UDP_Socket::get_NET_Session(uint32 uid)
{
	return get_UDP_Session(uid);
}



UDP_Session* UDP_Socket::CreateSession(uint32 ip, uint16 port, const char* szAddr)
{
	UDP_Session* pRet	= NULL;
	LOCK_CS(&m_lock_map_session);
	if(m_map_session.size()<=m_uid_lmt_max - m_uid_lmt_min)
	{
		//获取唯一的id
		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;
			}
		}

		if(uid>0)
		{
			pRet	= new UDP_Session(uid, this);
			if(pRet==NULL)
				return NULL;
			m_map_session[uid]	= pRet;
			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);
				}


			pRet->time_set(Sys_GetTime());
			pRet->RunTransfersThread();

		}

	}
	UNLOCK_CS(&m_lock_map_session);


	return pRet;
}

UDP_Session* UDP_Socket::CreateSession(sockaddr_in *ptr_addr)
{
	if(NULL==ptr_addr)
		return NULL;

	return CreateSession(ntohl(ptr_addr->sin_addr.s_addr), ntohs(ptr_addr->sin_port));
}

UDP_Session* UDP_Socket::CreateUniqueSession(uint32 ip, uint16 port, uint32 uid_unique, const char* szAddr)
{
	if(m_map_session.find(uid_unique)!=m_map_session.end())
		return false;

	UDP_Session *pRet	= new UDP_Session(uid_unique, this);
	m_map_session[uid_unique]	= pRet;
	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);
	}
				
				
	pRet->time_set(Sys_GetTime());
	pRet->RunTransfersThread();

	return pRet;
	
}

void UDP_Socket::CloseSession(uint32 uid)
{
	UDP_Session* pSession = NULL;
	LOCK_CS(&m_lock_map_session);
	std::map<uint32, UDP_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);



}





bool UDP_Socket::RunTransfersThread()
{
//	DWORD dwThreadId; 
//	m_thread_transfers = CreateThread( 
//										NULL,                        // default security attributes 
//										0,                           // use default stack size  
//										thread_UDP_transfers,        // thread function 
//										(LPVOID)this,						 // argument to thread function 
//										0,                           // use default creation flags 
//										&dwThreadId);                // returns the thread identifier 
 
//	if(m_socket<0)
//		return false;
//
//	m_thread_transfers	= CREATE_THREAD(thread_UDP_transfers, this);
//
//	if(m_thread_transfers)
//		return true;
//	else
//		return false;


	if(false==m_thread_pool.RunThread("recv_thread", thread_UDP_recv, this))
		return false;
	if(false==m_thread_pool.RunThread("send_thread", thread_UDP_send, this))
		return false;

	return true;

}


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


void UDP_Socket::CleanupSessionMap()
{
	LOCK_CS(&m_lock_map_session);
	std::map<uint32, UDP_Session*>::iterator it = m_map_session.begin();
	while(it!=m_map_session.end())
	{
		UDP_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);

}



void UDP_Socket::CheckConnect(time_t time)
{
	if(m_socket<=0)
		return;
	LOCK_CS(&m_lock_map_session);
	std::map<uint32, UDP_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 UDP_Socket::PushRecvPacket(NET_Packet* ptr_packet, time_t time)
{
	if(ptr_packet==NULL)
		return false;

	//在这里处理被动连接
	if(ptr_packet->getCmd()==NLIBP_CONNECT)
	{
		UDP_Session* pSession = get_UDP_Session(ptr_packet->getUID());
		uint32 uid	= ptr_packet->getSID();
		if(pSession)
		{//已连接,是连接确认信息
			pSession->time_set(time);
			if(pSession->m_uid_opposite==0)
				pSession->m_uid_opposite	= uid;
			pSession->m_addr_in	= *ptr_packet->get_addr();
		}
		else
		{//没有连接,创建会话并回复连接确认
			pSession = CreateSession(ptr_packet->getIP(), ptr_packet->getPort());
			if(pSession)
			{
				pSession->m_uid_opposite	= uid;
				pSession->Connect();
			}
		}
		//delete(ptr_packet);
		//return true;
		ptr_packet->setUID(pSession->getUID());
	}

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

NET_Packet*	UDP_Socket::PopRecvPacket()
{

	return NET_Socket::PopRecvPacket();
}



bool UDP_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;
	}
	ptr_packet->setSID(pSession->getUID());
	ptr_packet->setUID(pSession->getUID_opposite());
	LOCK_CS(&m_lock_send_packet);

//	ptr_packet->setSendto(uid_sendto);
	m_lst_send_packet.push_back(ptr_packet);
	UNLOCK_CS(&m_lock_send_packet);

	return true;
}


NET_Packet*	UDP_Socket::PopSendPacket()
{
	NET_Packet* pRet;
	LOCK_CS(&m_lock_send_packet);
	if(m_lst_send_packet.begin()!=m_lst_send_packet.end())
	{
		pRet	= *m_lst_send_packet.begin();
		m_lst_send_packet.pop_front();
	}
	else
		pRet	= NULL;
	UNLOCK_CS(&m_lock_send_packet);

	return pRet;
}


bool UDP_Socket::LockSendList()
{
	LOCK_CS(&m_lock_send_packet);
	return true;
}

void UDP_Socket::UnlockSendList()
{
	UNLOCK_CS(&m_lock_send_packet);
}


void UDP_Socket::CleanupSendList()
{
	LOCK_CS(&m_lock_send_packet);
	std::list<NET_Packet*>::iterator it = m_lst_send_packet.begin();
	while(it!=m_lst_send_packet.end())
	{
		if(*it)
			delete(*it);
		it++;
	}
	m_lst_send_packet.clear();
	UNLOCK_CS(&m_lock_send_packet);

}

uint16 UDP_Socket::getPort()
{

	return 0;
}

uint32 UDP_Socket::getIP()
{

	return 0;
}


bool UDP_Socket::change_session_uid(uint32 uid, uint32 uid_to)
{
	LOCK_CS(&m_lock_map_session);
	std::map<uint32, UDP_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
	{
		UDP_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;

}

void UDP_Socket::Ping(uint32 uid)
{
	if(uid==0)
	{
		LOCK_CS(&m_lock_map_session);
		std::map<uint32, UDP_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 + -
显示快捷键?