DragonNest/Common/NetworkLib/NetSocketUDP.cpp

226 lines
5.2 KiB
C++
Raw Permalink Normal View History

#include "stdafx.h"
#include "NetSocketUDP.h"
#include "NetSocketRUDP.h"
#include "DNPacket.h"
#include "ClientSessionManager.h"
#include <MMSystem.h>
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
CNetSocketUDP::CNetSocketUDP(const char * szNick, CNetSocketRUDP * pSocket) : Thread(szNick)
{
memset(&m_DirectionAddr, 0, sizeof(SOCKADDR_IN));
memset(&m_DetectAddr, 0, sizeof(_ADDR));
m_hSocket = INVALID_SOCKET;
m_UDPIP = 0;
m_UDPPort = 0;
m_pReciever = NULL;
m_pNetSocket = pSocket;
}
CNetSocketUDP::~CNetSocketUDP()
{
m_bRunning = false;
if (WaitForTerminate(100) == false)
Terminate(0);
if (m_hSocket != INVALID_SOCKET)
{
closesocket(m_hSocket);
m_hSocket = INVALID_SOCKET;
}
}
void CNetSocketUDP::DetectAddr(const char * ip, int port)
{
if (port <= 0) return;
if (m_DetectAddr.port > 0) return ;
unsigned long iIP = _inet_addr(ip);
memcpy(m_DetectAddr.ip, &iIP, 4);
m_DetectAddr.port = port;
if (m_DetectAddr.port > 0)
{//NATProbe<62><65> <20><><EFBFBD>Ͽ<EFBFBD> UDP IP<49><50> Port<72><74> <20>˾<EFBFBD> <20><><EFBFBD>ϴ<EFBFBD>.
for (int i = 0; m_UDPPort == 0 && i < 4000; i +=4000/10)
{
SOCKADDR_IN addr;
addr.sin_family = AF_INET;
addr.sin_port = ntohs(m_DetectAddr.port);
addr.sin_addr.S_un.S_addr = _inet_addr(m_DetectAddr.ip);
sendto(m_hSocket, "ping", 4, 0, (struct sockaddr *)&addr, sizeof(addr));
Sleep(4000/10);
}
}
}
void CNetSocketUDP::SetReciever(CRUDPReceiver * pReciever)
{
m_pReciever = pReciever;
}
bool CNetSocketUDP::Create(int port)
{
SOCKET sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sock == INVALID_SOCKET) return false;
SOCKADDR_IN addr;
ZeroMemory(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = port;
addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
if (::bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == SOCKET_ERROR)
{
closesocket(sock);
return false;
}
DWORD dwMode = 1;
::ioctlsocket( sock, FIONBIO, &dwMode );
m_hSocket = sock;
m_bRunning = true;
Start();
return true;
}
int CNetSocketUDP::Send(unsigned int main_header, unsigned int sub_header, void * data, int size, unsigned long addr, unsigned short port)
{
unsigned char packet[1024*4];
SetDirection(addr, port); //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD>!
int enlen = EncodeGamePacket(&packet, main_header, sub_header, data, size);
return SendTo(&packet, enlen, &m_DirectionAddr);
}
void CNetSocketUDP::Receive(void * data, int size, _ADDR * addr)
{
char * ptr;
int packetsize, i=0;
DNGAME_PACKET * p;
if (size <= 0)
return;
if (m_DetectAddr.port != 0 && addr->port == ntohs(m_DetectAddr.port) && _inet_addr(addr->ip) == _inet_addr(m_DetectAddr.ip))
{
struct _RETURN_UDP_ADDR
{
unsigned short port[2];
unsigned long addr[2];
} * packet = (_RETURN_UDP_ADDR*)data;
_ASSERT(addr->port == ntohs(m_DetectAddr.port) && _inet_addr(addr->ip) == _inet_addr(m_DetectAddr.ip));
if (size == sizeof(*packet) && packet->port[0] == packet->port[1] && packet->addr[0] == packet->addr[1] && m_UDPPort == 0)
{
m_UDPIP = packet->addr[0];
m_UDPPort = packet->port[0];
}
return ;
}
for(i=0; i<size;) // <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>Ŷ<EFBFBD><C5B6><EFBFBD><EFBFBD> <20><> ó<><C3B3>
{
ptr = (char*)data + i;
packetsize = CalcGamePacketSize((DNGAME_PACKET*)ptr, size - i);
if (i+packetsize > size)
break;
p = (DNGAME_PACKET*)ptr;
if (DecodeGamePacket(p) == true)
{
if (p->header == 2 && p->sub_header == 62) _ASSERT(0);
//m_pNetSocket->RecvData(p);
}
i += packetsize;
}
}
unsigned short CNetSocketUDP::GetPort()
{
if (m_UDPPort > 0)
return m_UDPPort;
SOCKADDR_IN addr;
int addrlen = sizeof(sockaddr_in);
getsockname(m_hSocket, (struct sockaddr*)&addr, &addrlen);
return htons(addr.sin_port);
}
unsigned long CNetSocketUDP::GetIP()
{
return m_UDPIP;
}
int CNetSocketUDP::SendTo(void * data, int size, SOCKADDR_IN * addr)
{
sendto(m_hSocket, (char*) data, size, 0, (struct sockaddr *)addr, sizeof(*addr));
return size;;
}
void CNetSocketUDP::SetDirection(unsigned long iIP, unsigned short iPort)
{
memset(&m_DirectionAddr, 0, sizeof(m_DirectionAddr));
m_DirectionAddr.sin_family = AF_INET;
m_DirectionAddr.sin_port = htons(iPort);
m_DirectionAddr.sin_addr.S_un.S_addr = iIP;
}
void CNetSocketUDP::Run()
{
char buffer[CLIENTPACKETMAX];
SOCKADDR_IN remote_addr;
int remote_addrlen, readbytes;
unsigned long totalbytes, i;
fd_set fdset;
srand(timeGetTime());
while (m_bRunning == true)
{
timeval tm;
tm.tv_sec = 0;
tm.tv_usec = 500;
FD_ZERO(&fdset);
FD_SET(m_hSocket, &fdset);
if (select(FD_SETSIZE, (fd_set*)&fdset, (fd_set*)0, (fd_set*)0, &tm) != SOCKET_ERROR)
{
if (fdset.fd_count > 0 && m_bRunning == true)
{
ioctlsocket(m_hSocket, FIONREAD, &totalbytes);
for(i=0; i<totalbytes;)
{
remote_addrlen = sizeof(remote_addr);
readbytes = recvfrom(m_hSocket, buffer, sizeof(buffer), 0, (struct sockaddr*) &remote_addr, &remote_addrlen);
i += readbytes;
if (readbytes > 0)
{
_ADDR addr;
addr.ip[0] = remote_addr.sin_addr.S_un.S_un_b.s_b1;
addr.ip[1] = remote_addr.sin_addr.S_un.S_un_b.s_b2;
addr.ip[2] = remote_addr.sin_addr.S_un.S_un_b.s_b3;
addr.ip[3] = remote_addr.sin_addr.S_un.S_un_b.s_b4;
addr.port = remote_addr.sin_port;
Receive(buffer, readbytes, &addr); // remote_addr <20><><EFBFBD><EFBFBD> <20><><EFBFBD>۵Ǿ<DBB5><C7BE><EFBFBD> (<28><><EFBFBD><EFBFBD> IP <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̽<EFBFBD><CCBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
}
}
}
}
}
}