📄 sockets.cpp
字号:
#include "sockets.h"
#include "encdec.h"#include "client.h"#include "server.h"
cSocket::cSocket()
{
FD_ZERO(&fdSocket);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
dbSocket = INVALID_SOCKET;
srvSocket = INVALID_SOCKET;
socketCount = 0;
memset(LSocket, INVALID_SOCKET, sizeof(LSocket));
}
cSocket::~cSocket()
{
sSocket *ptrSocket = LSocket;
for(u32 var = 0; var < socketCount; ptrSocket++)
{
if(ptrSocket->Sock != INVALID_SOCKET)
{
closesocket(ptrSocket->Sock);
ptrSocket->Sock = INVALID_SOCKET;
var++;
}
}
socketCount = 0;
FD_ZERO(&fdSocket);
}
// Le o arquivo de configuracao do socket//// Retorna false se o arquivo nao foi encontrado// Retorna true se o arquivo foi lido com sucesso
bool cSocket::ReadConfig()
{ const char *def = "socket.ini";
FILE *fp = fopen(def, "r");
if(fp == NULL)
{ /* not found */
Log(WARN, Server.GetMessage(FILENOTFOUND), def);
return false;
}
char cmd[16], val[16];
while(fgets(bufRecv, sizeof(bufRecv), fp))
{
if(bufRecv[0] == '#' || bufRecv[0] == '\n')
continue;
sscanf(bufRecv, "%s = %s", cmd, val);
if(strcmp(cmd, "srvIP") == 0)
strcpy(srvIP, val);
else if(strcmp(cmd, "srvPort") == 0)
srvPort = atoi(val);
else if(strcmp(cmd, "dbIP") == 0)
strcpy(dbIP, val);
else if(strcmp(cmd, "dbPort") == 0)
dbPort = atoi(val);
}
fclose(fp);
Log(NORMAL, Server.GetMessage(FILELOADED), def);
return true;
}
// Inicia a conexao do socket do server
//
// Retorna false se ocorreu um erro durante a cricao do socket
// Retorna true se o socket foi iniciado com sucesso
bool cSocket::StartServer()
{
srvSocket = socket(AF_INET, SOCK_STREAM, 0);
if(srvSocket == INVALID_SOCKET)
{ // Erro ao criar o socket
Log(WARN, "socket() failed in cSocket::StartServer()");
}
else
{ // Executa o bind
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(srvIP);
addr.sin_port = htons(srvPort);
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
if(bind(srvSocket, (sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR)
{ // Erro ao executar a funcao bind
Log(WARN, "bind() failed in cSocket::StartServer()");
}
else
{ // Executa o listen e adiciona o socket
if(listen(srvSocket, 8) == SOCKET_ERROR)
{ // Erro ao executar a funcao listen
Log(WARN, "listen() failed in cSocket::StartServer()");
}
else
{ // Adiciona o socket do servidor na lista dos sockets
sSocket sSock;
sSock.clientID = 0;
sSock.lastPacket = 0;
sSock.Sock = srvSocket;
sSock.socketInfo = addr;
AddSocket(sSock, 0);
return true;
}
}
}
return false;
}
// Inicia a conexao do socket da database
//
// Retorna false se ocorreu um erro durante a cricao do socket
// Retorna true se o socket foi iniciado com sucesso
bool cSocket::StartDatabase()
{
dbSocket = socket(AF_INET, SOCK_STREAM, 0);
if(dbSocket == INVALID_SOCKET)
{ // Erro ao criar o socket
Log(WARN, "socket() failed in cSocket::StartDatabase()");
}
else
{ // Conecta na database
sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(dbIP);
addr.sin_port = htons(dbPort);
memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
if(connect(dbSocket, (sockaddr*)&addr, sizeof(sockaddr_in)) == SOCKET_ERROR)
{ // Database nao foi encontrada
Log(WARN, "connect() failed in cSocket::StartDatabase()");
}
else
{ // Envia os pacotes de login u32 helloPacket = 0x1F11F311; if(send(dbSocket, (char*)&helloPacket, 4, 0) != 4) { // Erro ao enviar o pacote de hello Log(WARN, Server.GetMessage(ERRORSEND)); } else { // Envia o pacote de login sSocket sSock; sSock.clientID = DATABASE_ID; sSock.lastPacket = time(NULL); sSock.Sock = dbSocket; sSock.socketInfo = addr; // Header pDB_1h *pServer = (pDB_1h*)bufRecv; pServer->Header.packetSize = sizeof(pDB_1h); pServer->Header.opCode = 0x001; pServer->Header.clientID = 0; pServer->isGameServer = 1; if(!cClient::Send(sSock, bufRecv, sizeof(pDB_1h))) { // Erro ao enviar o pacote de login Log(WARN, Server.GetMessage(ERRORSEND)); } else { // Adiciona o socket da database na lista dos sockets
AddSocket(sSock, 1);
return true; } } // Fecha a conexao da database closesocket(dbSocket); dbSocket = INVALID_SOCKET;
}
}
return false;
}
// Verifica se o socket esta inativo
void cSocket::CheckSockets()
{
sSocket *ptrSock = &LSocket[2];
for(u32 x = 2; x < socketCount; ptrSock++)
{ // Procura os socket validos
if(ptrSock->Sock != INVALID_SOCKET)
{ // Socket valido
int timenow = time(NULL);
if(ptrSock->clientID == INVALID_ID)
{ // Client ainda nao se logou
if((ptrSock->lastPacket + 5) < timenow)
{ // Tempo maximo de espera pelo pacote de login
DeleteSocket(*ptrSock);
continue;
}
} else if((ptrSock->lastPacket + 305) < timenow) { // Client nao enviou nenhum pacote Log(INFO, Server.GetMessage(CLOSINGCLIENTTIME), ptrSock->clientID); // Deleta o client da lista DeleteSocket(*ptrSock); continue; }
x++;
}
} ptrSock = &LSocket[1]; if((ptrSock->lastPacket + 55) < time(NULL)) { // Envia o pacote de ping para nao ser desconectado pDB_2h *pServer = (pDB_2h*)bufRecv; pServer->Header.packetSize = sizeof(pDB_2h); pServer->Header.opCode = 0x002; pServer->Header.clientID = 0; if(!cClient::Send(*ptrSock, bufRecv, sizeof(pDB_2h))) { // Erro ao enviar o pacote de ping Log(WARN, Server.GetMessage(PINGERROR)); GameServer->CloseApp(); return ; } // Atualiza a ultima data do envio de um pacote ptrSock->lastPacket = time(NULL); }
}
// Adiciona o socket//// Retorna false se a lista esta cheia// Retorna true se o socket foi adicionado
bool cSocket::AddSocket(sSocket &sSock, s32 id)
{
if(id == -1)
{ // Procura uma id que nao esta sendo usada
for(id = 2; id < FD_SETSIZE; id++)
if(LSocket[id].Sock == INVALID_SOCKET)
break;
if(id == FD_SETSIZE)
return false;
}
if(sSock.Sock >= maxfd)
maxfd = sSock.Sock + 1;
socketCount++;
LSocket[id] = sSock;
FD_SET(sSock.Sock, &fdSocket);
return true;
}
// Aceita novos clients no socket do servidor
//
// Retorna false se o socket do servidor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -