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