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 + -
显示快捷键?